Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 在x86 8086程序集中生成0-9范围内的随机数_Assembly_Random_X86_X86 16 - Fatal编程技术网

Assembly 在x86 8086程序集中生成0-9范围内的随机数

Assembly 在x86 8086程序集中生成0-9范围内的随机数,assembly,random,x86,x86-16,Assembly,Random,X86,X86 16,首先,我对8086组装非常陌生,对我来说掌握这些知识非常困难。不过,我会尽我最大的努力 我一直在尝试编写一个代码来生成0-9范围内的随机数。在研究了几个例子和建议之后,这就是我的结论。为了简单起见,我没有对检索到的时钟计数应用任何数学函数,而且我认为这是不必要的。由于某些原因,我最终生成的某些数字(如6,7)比1,3和9等数字少。我相信这是因为我取的是时钟滴答声的较低阶,值的变化非常快 我的目的是模拟掷骰子,稍后会将下面代码的范围更改为1-6。 我的问题是,这是否足以满足我的目的?还是有更好的方

首先,我对8086组装非常陌生,对我来说掌握这些知识非常困难。不过,我会尽我最大的努力

我一直在尝试编写一个代码来生成0-9范围内的随机数。在研究了几个例子和建议之后,这就是我的结论。为了简单起见,我没有对检索到的时钟计数应用任何数学函数,而且我认为这是不必要的。由于某些原因,我最终生成的某些数字(如6,7)比1,3和9等数字少。我相信这是因为我取的是时钟滴答声的较低阶,值的变化非常快

我的目的是模拟掷骰子,稍后会将下面代码的范围更改为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 2.我们清除了DX。 3.我们于12月10日迁至CX。
4.我们将AX除以CX,因此得到0-9 Dec内的余数,该余数存储在DX 5中。最后,我们将ASCII“0”(Dec 48)添加到DX中,以将其转换为ASCII“0”到“9”。

此技巧仅在您需要一个随机数时有效,或者随机数之间的间隔包括人工输入的暂停。在所有其他情况下,这些数字根本不是随机的

如果您需要许多随机数,那么可以使用不同的伪随机数算法

另一个注意事项是,有更简单的方法可以在所需的时间间隔内获取数字:

    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'

当然,您可以对每个随机数生成器使用此方法。

我找到了一个较小的操作码,AAM-Ascii Adjust for乘法,用于此作业。此操作码的工作原理:

AH := AL / 10
AL := AL mod 10
因此,这将是:

mov al, dl
aam
add al, '0'
mov dl, al

您希望输出的范围是1-10(如标题所示)还是0-255(如问题所示:…生成一个一字节的随机数)?代码看起来像是在用ASCII码做一个从
0
9
的范围。是的,就像标题一样,准确地说是0-9。我试过你的代码,它工作得非常完美。和我的相比,它花费的时间更少。但有几件事我并不完全明白。1.xor dx,dx-这是为了什么?2.添加dl,“0”-通过将“0”添加到dl,我们如何实际实现0-9之间的ASCII值?我们不是将0(零)添加到dl,而是字符“0”=30h=48的ASCII代码。这样,DL中的数字(从0到9)将变为30h到39h,即从“0”到“9”的字符。我明白了,所以我们做了:1.我们把DX中的值移到ax2.我们清除了DX。3.我们于12月10日迁至CX。4.我们将AX除以CX,因此得到0-9 Dec内的余数,该余数存储在DX 5中。最后,我们将ASCII“0”(Dec 48)添加到DX中,以将其转换为ASCII“0”到“9”。好的,谢谢