Categories
Assembly Programming Languages

Generating Random Numbers in ASM using EMU8086

In this article, we’ll explore how to generate random numbers in Assembly language (ASM) using the EMU8086 emulator. Generating random numbers is a fundamental technique in many programming applications, and in assembly, we can achieve it using some system interrupts and basic arithmetic operations.

ASM Code to Generate Random Numbers

Below is the complete ASM code that generates a random number between 1 and 100:

org 100h
include emu8086.inc

xor ax, ax
mov es, ax

; Push the flag register onto the stack and access the Interrupt Vector Table (IVT)
pushf                
; Directly call "Int 1ah/ah=0" to get the CPU clock ticks since midnight, considered a semi-random number. 
call far es:[1ah*4]  
;The value is stored in DX.
mov ax, dx

xor dx, dx
xor bx, bx
; Divide the value by 100
; This gives a value between 0-99
mov bx, 100          
div bx               
; Increment the value by 1 to get a range of 1-100
inc dx               

mov ax, dx
call PRINT_NUM_UNS

ret

DEFINE_PRINT_NUM_UNS

END

Let’s break down the code step by step to understand how it works:

  1. Initialization and Configuration:
org 100h
include emu8086.inc

xor ax, ax
mov es, ax

These lines initialize the program and configure the necessary registers. org 100h sets the origin of the code, and include emu8086.inc includes the predefined macros and functions of the emulator. xor ax, ax and mov es, ax clear the AX register and set ES to 0.

2. Obtaining a Semi-Random Number:

pushf
call far es:[1ah*4]
mov ax, dx

We use interrupt 1Ah (system clock) to get the clock ticks since midnight, which gives us a semi-random value in the DX register.

Why Consider the Number Obtained as Pseudo-Random with Interrupt 1Ah?

The interrupt 1Ah (INT 1Ah) is used to access the system’s real-time clock (RTC) and retrieve the number of ticks that have occurred since midnight. The RTC operates independently of the CPU and keeps track of the time even when the system is powered off, thanks to a small battery. Each tick represents a small, fixed interval of time (usually 55 milliseconds on a standard PC).

When we call interrupt 1Ah, we obtain the current tick count, which is a continuously incrementing value. This value changes rapidly as time progresses, making it difficult to predict its exact value at any given moment. However, since it is based on a deterministic clock, it is not truly random but rather pseudo-random. This means that while the sequence of ticks is predetermined by the system clock, the specific value retrieved at a random moment is sufficiently unpredictable for many practical purposes.

In our context, using INT 1Ah to generate a pseudo-random number is effective because:

  • The tick count changes quickly and regularly.
  • The exact moment when the interrupt is called introduces variability.
  • It provides a simple method to obtain varying values without requiring complex algorithms or additional hardware.

Therefore, the number obtained using interrupt 1Ah is considered pseudo-random and can be effectively used in applications where true randomness is not critical but a certain level of unpredictability is desired.

3. Adjusting the Random Number Range:

xor dx, dx
xor bx, bx
mov bx, 100
div bx
inc dx

To adjust the value to a specific range, we first clear DX and BX. Then, we set BX to 100 and divide the value in AX by 100, giving us a number between 0 and 99 in DX. Finally, we increment DX by 1 to get a value between 1 and 100.

4. Displaying the Generated Number:

mov ax, dx
call PRINT_NUM_UNS
ret

We move the generated number to AX and use the macro PRINT_NUM_UNS to display the number on the screen. The program ends with the ret instruction.

This code demonstrates a simple and effective way to generate random numbers in assembly using EMU8086. By using system clock ticks and adjusting the range through arithmetic operations, we can obtain random numbers useful for various applications.