Generating a random number within range of 0-9 in x86 8086 Assembly

Raf picture Raf · Jul 25, 2013 · Viewed 49.8k times · Source

First of all, I am very new to 8086 Assembly and it has been pretty difficult for me the grab the knowledge. Nevertheless, I'll do my best.

I have been trying to write a code to generate a random number within range of 0-9. After looking into several examples and suggestion, this is what I ended up with. I did not apply any mathematical function on the retrieved clock count, for simplicity and also I thought it was unnecessary. I ended up with, for some reasons, generating certain number like 6,7 fewer times than numbers such as 1,3 and 9. I believe it is because I'm taking the lower order of the clock ticks, where the values change so rapidly.

My purpose is to simulate a dice roll which later ill change the range of below codes to 1-6. My question is, Is this adequate enough for my purpose? or is there any better way to do this?

codes:

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

Answer, by @johnfound:

I found his way is simpler, and takes less time to generate the random number. He mentioned that this works only if you need one single random numbers, or the interval between the random numbers includes pauses for human input. If not, the numbers will not be random at all (I believe due to the time seed that we initially take doesn't change). It is fine for my case, since I am simulating a roll dice, and I need the user intervention (another roll) before I will be running the code again.

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    

What he did: 1.We moved value in DX to AX 2.We cleared DX. 3.We moved 10 dec to CX. 4.We divided AX by CX hence we get a remainder within 0-9 Dec which is stored in DX 5.Finally, we added ASCII '0' (dec 48) to DX to get them into ASCII '0' to '9'.

Answer

johnfound picture johnfound · Jul 25, 2013

This trick works only if you need one single random numbers, or the interval between the random numbers includes pauses for human input. In all other cases, the numbers will not be random at all.

If you need many random numbers, then there are different pseudo-random number algorithms available.

Another note is that there is more easy way to get the number in the needed interval:

    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'

You can use this method for every random number generator of course.