在程序集

时间:2016-02-23 16:48:45

标签: assembly random x86 masm emu8086

我是汇编的新手,我在生成随机数时遇到了问题。

我的代码很简单:它在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

我的代码中是否有问题?我需要添加一些东西吗?感谢。

2 个答案:

答案 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个高位中必须是奇数且非零。
  • Weyl序列存储在cx中,并通过在每次迭代时添加bx获得。

与标准中间平方法不同,将其与Weyl序列组合可防止向随机数序列的0收敛。我建议阅读上面提到的出版物以获取更多信息。