Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating random numbers in assembly

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.

like image 793
Hamza Anis Avatar asked Mar 13 '23 04:03

Hamza Anis


2 Answers

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:

    mul ax      ; square random number
    add cx, bx  ; calculate next iteration of Weyl sequence
    add ax, cx  ; add Weyl sequence
    mov al, ah  ; get lower byte of random number from higher byte of ax
    mov ah, dl  ; get higher byte of random number from lower byte of dx
    ...         ; use new random number stored in ax

A few notes about the above code:

  • The random number is stored in ax.
  • The initial seed is stored in 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.
  • The Weyl sequence is stored in cx, and obtained by adding bx 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.

like image 26
Pyves Avatar answered Mar 24 '23 16:03

Pyves


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:

; here ax contains the previous number

    mul ax
    mov al, ah
    mov ah, dl 

; here ax contains the next pseudo random number.
like image 118
johnfound Avatar answered Mar 24 '23 16:03

johnfound