I am new to assembly, and I am having problems generating random numbers.
My code is simple: it generates 100 numbers in the 0-25
range and stores them in an array.
The problem I am experiencing is that when I run the con on the emu8086
assembler it runs successfully and generates 100 random numbers, that are stored in the array. But when I run it on the masm611
, it generates a new random number every 4 cycles. Which means the values in the array are consecutive same number for 4 values and then next random value is stored.
Here is my code:
.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
Is there is a problem in my code? Do I need to add something? Thanks.
The main problem of your code is that it does not generate random numbers at all. Because the system clock is not random number generator. I would say, it is very non-random number generator.
The first time read after the start of the program still can be considered "random", but only if you run the program manually in random moment in time.
All next numbers will be not random at all.
This way, the value read from the system clock is suitable for use as a seed (starting value) of some other algorithm for generation of (pseudo)random numbers.
The random (and pseudo random) number generators are complex topic, that need some study. Start at least with wikipedia.
BTW, despite of the complexity of the topic as a whole, some random number generators are simple enough to be implemented by beginner programmers. For example middle-square-method. Try to implement it in assembly language by multiplying the current seed AX by itself and form the next number by the middle 4 hexadecimal digits of the result:
To build upon johnfound's answer, you could make a more robust random number generator by running the middle-square method he described with a Weyl sequence. This is based on ideas from Middle Square Weyl Sequence RNG, published by Bernard Widynski on 4th April 2017.
An assembly implementation could be built along the following lines:
A few notes about the above code:
ax
.bx
(you could for instance use something derived from the system's clock). The seed must be odd and non-zero in the 8 upper bits.cx
, and obtained by addingbx
at each iteration.Unlike the standard middle-square method, combining it with a Weyl sequence prevents convergence towards 0 of the random number sequence. I recommend reading the publication mentioned above for additional information.