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'.
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.