assembly 汇编代码中的随机数发生器

wb1gzix0  于 2023-03-08  发布在  其他
关注(0)|答案(3)|浏览(178)

有谁知道如何编码一个8位数随机生成的汇编代码?
我正在使用ATmega8535与Atmel AVR汇编与AVR仿真器调试.(AVR Studio 4)
对不起,我是新来的,任何帮助都将不胜感激,谢谢

ikfrs5lh

ikfrs5lh1#

这取决于你对随机的理解。如果你只是想要一个可预测的数字序列,但具有统计随机性,那么在微控制器上实现最简单的是linear feedback shift register。在PIC设备上汇编实现的示例可以参见here
具有更好互相关特性的变体是Gold码,它稍微复杂一些,但也依赖于相同的原理。还有许多其他算法,但这实际上取决于您需要哪种统计特性。
如果需要高熵(即无法预测),则一种新颖的方法是使用器件的ADC对反向偏置二极管结上的电压进行采样。由此产生的噪声是一个强大的熵源。但是,需要注意的是,不要意外地向系统中引入任何阶数,因此设计时需要谨慎。

8i9zcol2

8i9zcol22#

有一个conversation on AVR Freaks讨论了汇编语言代码生成8位随机数,并带有一个注解,提供了一个内联汇编程序解决方案。
在此基础上......我编写了以下代码:

.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

还有another converstaion on AVR Freaks,它提供了一些选项......但这些选项非常难以阅读,因为它们缺少任何接近有意义的标识符的东西,而且它们的作者拒绝解释它们。

hzbexzde

hzbexzde3#

所以你实际上需要一个子系统,它可以根据一些几乎随机(或难以预测)的源生成随机数,同时保持足够的熵。
请记住,系统越简单,它提供的随机数就越少。
您可能会对以下内容感兴趣:

相关问题