【发布时间】:2015-03-17 11:46:32
【问题描述】:
有谁知道如何编码一个 8 位数字以在汇编代码中随机生成?
我正在使用带有 Atmel AVR 汇编器的 ATmega8535 以及 AVR 模拟器的调试。 (AVR 工作室 4)
对不起,我是新手,任何帮助将不胜感激 谢谢
【问题讨论】:
有谁知道如何编码一个 8 位数字以在汇编代码中随机生成?
我正在使用带有 Atmel AVR 汇编器的 ATmega8535 以及 AVR 模拟器的调试。 (AVR 工作室 4)
对不起,我是新手,任何帮助将不胜感激 谢谢
【问题讨论】:
这真的取决于你所说的随机是什么意思。如果您只想要一个可预测但具有统计随机性的数字序列,那么在微控制器上实现最简单的是linear feedback shift register。在 PIC 设备上的汇编实现示例可见 here。
具有更好互相关属性的变体是黄金代码,它稍微复杂一些,但依赖于相同的原理。还有很多其他的算法,但是这真的取决于你需要什么样的统计属性。
如果您需要高熵(即无法预测)的东西,那么一种新颖的方法是使用设备的 ADC 对反向偏置二极管结上的电压进行采样。由此产生的噪声是一个强大的熵源。但是,您需要注意不要意外地将任何顺序引入系统,因此在设计时需要小心。
【讨论】:
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 提供了一些选项...但这些选项非常难以阅读,因为它们缺少任何接近有意义的标识符并且它们的作者拒绝解释它们。
【讨论】:
因此,您实际上需要一个子系统,该子系统可以根据一些几乎随机(或难以预测)的源生成随机数,同时保持足够的熵。
请记住,系统越简单,它提供的随机数就越少。
您可能对以下内容感兴趣:
C 中实现它,可以很容易地移植到ASM。【讨论】: