【问题标题】:Random number generator in assembly code汇编代码中的随机数生成器
【发布时间】:2015-03-17 11:46:32
【问题描述】:

有谁知道如何编码一个 8 位数字以在汇编代码中随机生成?

我正在使用带有 Atmel AVR 汇编器的 ATmega8535 以及 AVR 模拟器的调试。 (AVR 工作室 4)

对不起,我是新手,任何帮助将不胜感激 谢谢

【问题讨论】:

    标签: assembly random avr


    【解决方案1】:

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

    具有更好互相关属性的变体是黄金代码,它稍微复杂一些,但依赖于相同的原理。还有很多其他的算法,但是这真的取决于你需要什么样的统计属性。

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

    【讨论】:

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

      【讨论】:

        【解决方案3】:

        因此,您实际上需要一个子系统,该子系统可以根据一些几乎随机(或难以预测)的源生成随机数,同时保持足够的熵。

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

        您可能对以下内容感兴趣:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-09-10
          • 1970-01-01
          • 1970-01-01
          • 2019-09-06
          • 1970-01-01
          • 1970-01-01
          • 2021-07-18
          相关资源
          最近更新 更多