汇编代码中的随机数生成器

时间:2015-03-17 11:46:33

标签: assembly avr

有没有人知道如何编写在汇编代码中随机生成的8位数字?

我正在使用带有Atmel AVR汇编程序的ATmega8535和AVR模拟器的调试。 (AVR Studio 4)

对不起,我是新手,任何帮助都会很感激 感谢

3 个答案:

答案 0 :(得分:2)

有一个 conversation on AVR Freaks 讨论了生成 8 位随机数的汇编语言代码 with a comment,它提供了一个内联汇编器解决方案。

基于此...我想出了以下代码:

    .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 提供了一些选项......但这些内容非常难以阅读,因为它们缺少任何接近有意义的标识符,而且它们的作者拒绝解释它们。

答案 1 :(得分:1)

这实际上取决于你的意思是随机的。如果您只想要一系列可预测但具有统计随机性的数字,那么在微控制器上实现的最简单的是linear feedback shift register。可以看到PIC设备上的汇编实现示例here

具有更好互相关属性的变化是Gold-Codes,它有点复杂但依赖于相同的原理。还有很多其他算法,但它实际上取决于你需要什么样的统计属性。

如果你需要具有高水平熵的东西(即无法预测),那么一种新颖的方法是使用器件的ADC对反向偏置二极管结上的电压进行采样。由此产生的噪声是强大的熵源。但是,您需要小心,不要意外地将任何订单引入系统,因此需要注意设计。

答案 2 :(得分:0)

所以你实际上需要一个基于一些几乎随机(或难以预测)的源生成随机数的子系统,该源也能保持足够的熵。

请记住,系统越容易,它提供的随机数就越少。

您可能会对此this和此this感兴趣。在第二个链接上,有一个有趣的讨论在C中实现这一点,可以很容易地移植到ASM