我是汇编的新手,我在生成随机数时遇到了问题。
我的代码很简单:它在0-25
范围内生成100个数字并将它们存储在数组中。
我遇到的问题是,当我在emu8086
汇编程序上运行con时,它成功运行并生成100个随机数,这些数字存储在数组中。但是当我在masm611
上运行它时,它会每4个周期生成一个新的随机数。这意味着数组中的值是4个值的连续相同数字,然后存储下一个随机值。
这是我的代码:
.model small
.stack 100h
.data
range db 25
i db 0 ;iterator
arr db 15 dup(0) ; an array
.code
mov ax,@data
mov ds,ax
mov bx,offset arr ;getting the adress of the arr in bx
L1:
mov ah,2ch
int 21h
mov ah,0
mov al,dl ;using dl by seeing 2ch details
div range ; so the number is in range
mov [bx],ah ;ah has remainder as using 8 bits div and
inc bx ;moving to the next index
inc i
cmp i,100
jbe L1
mov ah,4ch ;returning control
int 21h
end
我的代码中是否有问题?我需要添加一些东西吗?感谢。
答案 0 :(得分:6)
您的代码的主要问题是它根本不会生成随机数。因为系统时钟不是随机数发生器。我会说,它是非随机数字生成器。
程序启动后第一次读取仍然可以考虑"随机",但仅限于您在随机时间手动运行程序。
所有下一个数字都不是随机的。
这样,从系统时钟读取的值适合用作生成(伪)随机数的其他算法的种子(起始值)。
随机(和伪随机)数字生成器是一个复杂的主题,需要一些研究。至少从wikipedia开始。
BTW,尽管整个主题很复杂,但一些随机数生成器很容易被初学者程序员实现。例如middle-square-method。尝试用汇编语言实现它,方法是将当前种子AX乘以自身,然后用结果的中间4位十六进制数字形成下一个数字:; here ax contains the previous number
mul ax
mov al, ah
mov ah, dl
; here ax contains the next pseudo random number.
答案 1 :(得分:1)
基于johnfound的答案,你可以通过运行他用Weyl序列描述的中间平方法来制作更强大的随机数生成器。这是基于2017年4月4日Bernard Widynski出版的 Middle Square Weyl Sequence RNG 的想法。
可以按以下方式构建程序集实现:
mul ax ; square random number
add cx, bx ; calculate next iteration of Weyl sequence
add ax, cx ; add Weyl sequence
mov al, ah ; get lower byte of random number from higher byte of ax
mov ah, dl ; get higher byte of random number from lower byte of dx
... ; use new random number stored in ax
关于上述代码的一些注释:
ax
。bx
中(例如,您可以使用从系统时钟派生的内容)。种子在8个高位中必须是奇数且非零。cx
中,并通过在每次迭代时添加bx
获得。与标准中间平方法不同,将其与Weyl序列组合可防止向随机数序列的0收敛。我建议阅读上面提到的出版物以获取更多信息。