4

我是组装新手,在生成随机数时遇到问题。

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

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

4

2 回答 2

6

您的代码的主要问题是它根本不会生成随机数。因为系统时钟不是随机数发生器。我会说,它是非常非随机数生成器。

程序启动后的第一次读取仍然可以认为是“随机的”,但前提是您在随机时刻手动运行程序。

所有接下来的数字都不是随机的。

这样,从系统时钟读取的值适合用作某些其他算法的种子(起始值),以生成(伪)随机数。

随机(和伪随机)数生成器是复杂的主题,需要一些研究。至少从wikipedia开始。

顺便说一句,尽管整个主题很复杂,但一些随机数生成器足够简单,可以由初学者程序员实现。例如mid-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.
于 2016-02-23T19:22:04.343 回答
2

为了建立 johnfound 的答案,您可以通过运行他用外尔序列描述的中间平方方法来制作更强大的随机数生成器。这是基于Bernard Widynski 于 2017 年 4 月 4 日发表的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 收敛。我建议阅读上述出版物以获取更多信息。

于 2017-04-15T17:53:38.860 回答