Joe Cobain
Joe Cobain

Reputation: 91

Random number generator in assembly code

Does anyone know how to code a 8 bit numbers to be randomly generated in assembly code?

I'm using ATmega8535 with Atmel AVR Assembler with the Debug of AVR Simulator. (AVR Studio 4)

Sorry i am new to this and any help would be appreciate Thanks

Upvotes: 4

Views: 4167

Answers (3)

Andy Preston
Andy Preston

Reputation: 772

(Edit) It seems that all the conversations on AVR Freaks that I link to here have been deleted.

There's a conversation on AVR Freaks that discusses assembly language code to generate 8 bit random numbers with a comment that provides an inline assembler solution.

Based on this... I've come up with the following code:

    .device ATMega324P

    .def _high = r16
    .def _low = r17
    .def _mask = r18
    .def _step = r19
    .def _delay1 = r20
    .def _delay2 = r21

    .cSeg
    .org 0x0000
    jmp resetHandler

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    .dSeg
lfsr16High:
    .byte 1
lfsr16Low:
    .byte 1

    .cSeg

    .equ lfsr16Seed = 0xACE1

.macro setup16BitLFSR
    ldi _high, high(lfsr16Seed)
    ldi _low, low(lfsr16Seed)
    sts lfsr16High, _high
    sts lfsr16Low, _low
.endMacro

.macro randomByteFrom16BitLFSR
    lds _high, lfsr16High
    lds _low, lfsr16Low

    ; Masks for 16-bit LFSR.  Uncomment only one
    ldi _mask, 0x9C
    ; ldi _mask, 0xB4
    ; ldi _mask, 0xBD
    ; ldi _mask, 0xCA
    ; ldi _mask, 0xEB
    ; ldi _mask, 0xFC

    ldi _step, 8
step:                    ; run the LFSR 8 steps
    lsr _high
    ror _low
    brcc noMask          ; output bit set?
    eor _high, _mask     ; yes, apply mask
noMask:
    dec _step            ; done?
    brne step            ; no, loop

    sts lfsr16High, _high
    sts lfsr16Low, _low ; random byte is in _low register
.endMacro

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    .dSeg
lfsr8:
    .byte 1

    .cSeg

.macro setup8BitLFSR
    ldi _low, 0x37       ; seed value
    sts lfsr8, _low
.endMacro

.macro randomByteFrom8BitLFSR
    lds _low, lfsr8

    ; Masks for 8-bit LFSR. Uncomment only one
    ldi _mask, 0x8E
    ; ldi _mask, 0x95
    ; ldi _mask, 0x96
    ; ldi _mask, 0xA6
    ; ldi _mask, 0xAF
    ; ldi _mask, 0xB1
    ; ldi _mask, 0xB2
    ; ldi _mask, 0xB4
    ; ldi _mask, 0xB8
    ; ldi _mask, 0xC3
    ; ldi _mask, 0xC6
    ; ldi _mask, 0xD4
    ; ldi _mask, 0xE1
    ; ldi _mask, 0xE7
    ; ldi _mask, 0xF3
    ; ldi _mask, 0xFA

    ldi _step, 8
step:                    ; run the LFSR 8 steps
    ror _low             ; shift lfsr
    brcc  noMask         ; output bit set?
    eor _low, _mask      ; apply mask
noMask:
    dec _step            ; done?
    brne step            ; no, loop

    sts lfsr8, _low      ; random byte is in _low register
.endMacro

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    .cSeg

resetHandler:
    cli

    ldi _high, high(RamEnd)
    ldi _low, low(RamEnd)
    out SPH, _high
    out SPL, _low

    ldi _low, 0xff
    out DDRA, _low

    ; setup8BitLFSR
    setup16BitLFSR

tryAnotherOne:
    ; randomByteFrom8BitLFSR
    randomByteFrom16BitLFSR

    out PORTA, _low

    ldi _delay1, 0xFF
outerDelay:
    ldi _delay2, 0xFF
innerDelay:
    dec _delay2
    brne innerDelay
    dec _delay1
    brne outerDelay

    rjmp tryAnotherOne

There's also another converstaion on AVR Freaks that provides a few options... but these are incredibly hard to read as they lack anything approaching meaningful identifiers and their authors refuse to explain them.

Upvotes: 2

Andrew Dunai
Andrew Dunai

Reputation: 3129

So you actually need a subsystem that generates random numbers based on some nearly-random (or hard to predict) source that also maintains enough entropy.

Keep in mind that the easier the system will be, the less random numbers it will provide.

You might be interested in:

Upvotes: 0

Jon
Jon

Reputation: 506

It really depends on what you mean by random. If you just want a sequence of numbers that are predictable but have statistical randomness then the simplest to implement on a microcontroller is the linear feedback shift register. An example of an implementation in assembly on a PIC device can be seen here.

Variations with better cross-correlation properties are Gold-Codes which are a bit more complex but rely on the same principle. There are also a lot of other algorithms, but it really depends on what sort of statistical properties you require.

If you need something with a high level of entropy (i.e. can't be predicted) then a novel way is to use the device's ADC to sample the voltage on a reversed biased diode junction. The noise generated by this is a robust source of entropy. However, you need to be careful that you don't introduce any order into the system by accident so some care in the design is needed.

Upvotes: 5

Related Questions