UMBC CMSC 211

UMBC | CSEE


The 'Minimal Standard' Random Number Generator

A reasonable good random number generator is:

;; RANDOM.ASM--implementation of minimal standard random number
;;   generator.  See article by David G. Carta, CACM Jan 1990, p. 87
;;
;;   Calling Sequence:
;;
;;	EXTRN	Random: NEAR
;;	call	Random
;;   0 < value < 2**31 - 1 returned in dx|ax
;;
;;  Assumes seed has been set elsewhere as a PUBLIC double-word
;;  Assumes ds is set to @data.
;;
;;  Program text from "Assembly Language for the IBM PC Family" by
;;   William B. Jones, (c) Copyright 1992, 1997, Scott/Jones Inc.
;;
	.MODEL	SMALL
	.DATA
	EXTRN	Seed:DWORD ;	set by caller
A	EQU	16807
S0	EQU	WORD PTR Seed ;	Low order word of seed
S1	EQU	WORD PTR Seed+2 ;	High order word of seed

	.CODE
	PUBLIC	Random
Random	PROC
;
;	P2|P1|P0 := (S1|S0) * A
;
	mov	ax, S0
	mov	bx, A
	mul	bx
	mov	si, dx ;	si := pp01  (pp = partial product)
	mov	di, ax ;	di := pp00 = P0
	mov	ax, S1
	mul	bx ;	ax := pp11
	add	ax, si ;	ax := pp11 + pp01 = P1
	adc	dx, 0 ;	dx := pp12 + carry = P2
;
;	P2|P1:P0 = p * 2**31 + q, 0 <= q < 2**31
;
;	p = P2 SHL 1 + sign bit of P1 --> dx 
;		(P2:P1|P0 < 2**46 so p fits in a single word)
;	q = (P1 AND 7FFFh)|P0 = (ax AND 7fffh) | di
;
	shl	ax, 1
	rcl	dx, 1
	shr	ax, 1
;
;	dx:ax := p + q
;
	add	dx, di ;	dx := p0 + q0
	adc	ax, 0 ;	ax := q1 + carry
	xchg	ax, dx
;
;	if p+q < 2**31 then p+q is the new seed; otherwise whack
;	  off the sign bit and add 1 and THATs the new seed
;
	test	dx, 8000h
	jz	Store
	and	dx, 7fffh
	add	ax, 1 ;		inc doesn't set carry bit
	adc	dx, 0
Store:
	mov	S1, dx
	mov	S0, ax
	ret
Random	ENDP
	END


UMBC | CSEE