在 x86 程序集中生成伪随机字符
Generating a pseudo-random character in x86 assembly
我正在学习汇编,我找到了这段代码:
; Initialized seed value
xor [myseed], esp
; Generate random string
call randletter
mov [message], al ; Write 1st letter
; myrand gives a pseudo-random number in range 0..max
; inputs:
; edi - max value
; outputs:
; eax - generated value
myrand: mov eax, [myseed] ; Load state of generator
mov ecx, 4000000001
mul ecx ; Multiply state var by a constant
add eax, 3333333333 ; Add another constant
mov [myseed], eax ; And save the result
xor edx, edx
inc edi
div edi ; Divide state var in edx:eax by (max+1) in edi
mov eax, edx ; div instruction writes remainder into edx, so copy to eax
ret
; randletter gives a random lowercase letter
; inputs: no
; outputs:
; al - random lowercase letter (ASCII code)
randletter:
mov edi, 25
call myrand
add al, 'a'
ret
section .data
myseed: dd 123456789
现在我知道了,这是方法myrand
中的线性同余生成器。
我的问题是 myrand
中的数字如何导致 randletter
中 ASCII 中从 97 到 122 的数字?以及为什么他们在 myrand
中有 add al, a
。这有什么帮助?
小写字母的 ASCII 码从 'a' 的 97 到 'z' 的 122 不等。
myrand
(25) 的输出是从 0 到 25。
randletter:
mov edi, 25
call myrand ; -> EAX == [0,25]
add al, 'a' ; -> AL == [0,25] + 97 == [97,122] == ['a','z']
ret
无论 myseed 中的值如何,除法 div edi
都会根据 EDI=25+1
始终产生 0 到 25 之间的余数。此余数成为 myrand 函数的结果。
EDI=25
...
mov [myseed], eax ; And save the result
xor edx, edx ; EDX=0
inc edi ; -> EDI == 25 + 1 == 26
div edi ; Divide EDX:EAX by 26 -> remainder EDX == [0,25]
mov eax, edx ; return result in EAX
ret
导致 myseed 新值的计算仅对随机数分布的质量很重要。
输出范围的限制完全取除法的余数.
我正在学习汇编,我找到了这段代码:
; Initialized seed value
xor [myseed], esp
; Generate random string
call randletter
mov [message], al ; Write 1st letter
; myrand gives a pseudo-random number in range 0..max
; inputs:
; edi - max value
; outputs:
; eax - generated value
myrand: mov eax, [myseed] ; Load state of generator
mov ecx, 4000000001
mul ecx ; Multiply state var by a constant
add eax, 3333333333 ; Add another constant
mov [myseed], eax ; And save the result
xor edx, edx
inc edi
div edi ; Divide state var in edx:eax by (max+1) in edi
mov eax, edx ; div instruction writes remainder into edx, so copy to eax
ret
; randletter gives a random lowercase letter
; inputs: no
; outputs:
; al - random lowercase letter (ASCII code)
randletter:
mov edi, 25
call myrand
add al, 'a'
ret
section .data
myseed: dd 123456789
现在我知道了,这是方法myrand
中的线性同余生成器。
我的问题是 myrand
中的数字如何导致 randletter
中 ASCII 中从 97 到 122 的数字?以及为什么他们在 myrand
中有 add al, a
。这有什么帮助?
小写字母的 ASCII 码从 'a' 的 97 到 'z' 的 122 不等。
myrand
(25) 的输出是从 0 到 25。
randletter:
mov edi, 25
call myrand ; -> EAX == [0,25]
add al, 'a' ; -> AL == [0,25] + 97 == [97,122] == ['a','z']
ret
无论 myseed 中的值如何,除法 div edi
都会根据 EDI=25+1
始终产生 0 到 25 之间的余数。此余数成为 myrand 函数的结果。
EDI=25
...
mov [myseed], eax ; And save the result
xor edx, edx ; EDX=0
inc edi ; -> EDI == 25 + 1 == 26
div edi ; Divide EDX:EAX by 26 -> remainder EDX == [0,25]
mov eax, edx ; return result in EAX
ret
导致 myseed 新值的计算仅对随机数分布的质量很重要。
输出范围的限制完全取除法的余数.