;; 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 ;; ;; Library source text from "Assembly Language for the IBM PC Family" by ;; William B. Jones, (c) Copyright 1992, 1997 Scott/Jones Inc. ;; .MODEL SMALL .DATA Seed DD 1 ; Chosen to test routine 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 push ds ; No params or local data, so bp not needed mov ax, @data mov ds, ax ; ; 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 pop ds ret Random ENDP END