首先,我是8086大会的新手,抓住这些知识对我来说非常困难。不过,我会尽我所能。
我一直在尝试编写代码来生成0-9范围内的随机数。在研究了几个例子和建议之后,这就是我最终的结果。我没有对检索到的时钟计数应用任何数学函数,为简单起见而且我认为这是不必要的。由于某些原因,我最终得到了一些数字,比如1,3和9这样的数字少了6,7倍。我相信这是因为我采用了时钟滴答的较低阶,其中值改变了迅速。
我的目的是模拟一个骰子卷,后来将下面代码的范围改为1-6。 我的问题是,这足以达到我的目的吗?或者有更好的方法吗?
代码:
RANDGEN: ; generate a rand no using the system time
RANDSTART:
MOV AH, 00h ; interrupts to get system time
INT 1AH ; CX:DX now hold number of clock ticks since midnight
; lets just take the lower bits of DL for a start..
MOV BH, 57 ; set limit to 57 (ASCII for 9)
MOV AH, DL
CMP AH, BH ; compare with value in DL,
JA RANDSTART ; if more, regenerate. if not, continue...
MOV BH, 49 ; set limit to 48 (ASCII FOR 0)
MOV AH, DL
CMP AH, BH ; compare with value in DL
JB RANDSTART ; if less, regenerate.
; if not, this is what we need
mov ah, 2h ; call interrupt to display a value in DL
int 21h
RET
通过@johnfound回答:
我发现他的方式更简单,生成随机数的时间更短。他提到只有当你需要一个随机数时才有效,或者随机数之间的间隔包括人类输入的暂停。如果不是,这些数字根本不是随机的(我相信由于我们最初采取的种子不会改变)。这对我的情况很好,因为我正在模拟掷骰子,在我再次运行代码之前我需要用户干预(另一卷)。
RANDGEN: ; generate a rand no using the system time
RANDSTART:
MOV AH, 00h ; interrupts to get system time
INT 1AH ; CX:DX now hold number of clock ticks since midnight
mov ax, dx
xor dx, dx
mov cx, 10
div cx ; here dx contains the remainder of the division - from 0 to 9
add dl, '0' ; to ascii from '0' to '9'
mov ah, 2h ; call interrupt to display a value in DL
int 21h
RET
他做了什么: 1.我们将DX中的值移至AX 我们清除了DX。 我们将10月12日搬到了CX。 4.我们将AX除以CX,因此我们在12月0-9之间得到一个存储在DX 5中的余数。最后,我们将ASCII'0'(dec 48)添加到DX以使它们进入ASCII'0'到'9'
答案 0 :(得分:7)
此技巧仅在您需要一个随机数时才有效,或者随机数之间的间隔包括人类输入的暂停。在所有其他情况下,这些数字根本不是随机的。
如果您需要许多随机数,则可以使用不同的伪随机数算法。
另一个注意事项是,在所需的时间间隔内有更简单的方法来获取数字:
mov ax, dx
xor dx, dx
mov cx, 10
div cx ; here dx contains the remainder of the division - from 0 to 9
add dl, '0' ; to ascii from '0' to '9'
当然,您可以对每个随机数生成器使用此方法。
答案 1 :(得分:0)
我为这项工作找到了一个较小的操作码,AAM - Ascii Adjust for Multiplication。这个操作码如何工作:
AH := AL / 10
AL := AL mod 10
所以,就是这样:
mov al, dl
aam
add al, '0'
mov dl, al