Category : Recently Uploaded Files
Archive   : 80XXX_94.ZIP
Filename : RANDOM5.ASM

 
Output of file : RANDOM5.ASM contained in archive : 80XXX_94.ZIP
page 50, 132
DOSSEG
.MODEL small
.DATA?
seed dd ?
seed_diff dw ?

.CODE
; macros and equates
MULTIP EQU 764261123 ;From Marsaglia JASA article
LO_WORD EQU 0B303h ; MULTIP AND 0FFFFh
HI_WORD EQU 02D8Dh ; MULTIP >> 16

_newrand PROC NEAR
PUBLIC _newrand
; First part is just a double precision multiply, modifified for speed
; Register assignments:
; SI: 2^0 word of product
; AX: trashed by multiplications
; BX: 2^16 word
; CX: 2^32 word
; DX: trashed by multiplications
; DI: 2^48 word
; i.e.: DI:CX:BX:SI [AX & DX trashed]
push si ;preserve caller's registers
push di

xor di,di

mov ax,LO_WORD
mul WORD PTR [seed] ;arg1(lo) * arg2(lo)
mov si,ax ;2^0 coefficient word(s)
mov bx,dx
add bx,ax ;2^16 coefficient word(s)
; adc cx,dx
; adc di,0 ;carries into high words cannot occur
; for this _PARTICULAR_ multiplier
; and this _PARTICULAR_ modulus
; (I checked bounds on the arithmetic),
; so MOV can be used
mov cx,dx

mov ax,HI_WORD
mul WORD PTR [seed+2] ;arg1(hi) * arg2(hi)
add bx,ax ;2^16 coefficient word(s)
adc cx,dx
adc di,0
add cx,ax ;2^32 coefficient word(s)
adc di,dx

mov ax,HI_WORD-LO_WORD ; Knuth vol 2 p. 278
mul WORD PTR [seed_diff] ;(word diff 1) * -(word diff 2)
add bx,ax ;2^16 coefficient word(s)
adc cx,dx
adc di,0
; Next part is tricky. We want product we just computed taken modulo
; 2^31-1. Ordinarily this would be implemented as a _VERY_ time-
; consuming multiple-precision division to get the remainder. Instead,
; we exploit the identity
; n = q * (2^31 - 1) + r implying
; n = q * 2^31 - q + r which implies
; r = n - q * 2^31 + q
; where
; q = quotient
; r = remainder (i.e., product modulo 2^31-1)
; Now it's a lot easier to get the value of q: it's just the most significant
; bits in the quadword result. Also, r is (almost) just the least significant
; bits in this same result. To see this, we need to notice that the 64-bit
; quad word product lays out as
;
; word 3 | word 2 | word 1 | word 0
;64 48|47 32|31|30 16|15 0
; |
;\______________________________________/ \__________________________________/
; q r
;
; So, to get q, we just left shift bits 64..31 by 1.
; (This loses bit 64, but it's always zero for our choice of random number
; range 0..2^31-1 and our multiplier.)

shl bx,1
rcl cx,1
rcl di,1 ; DI:CX = q
shr bx,1 ; restore, less most sig. bit
; at this point we have shed bits 64:31 in the quad word result (i.e., we're
; going to essentially ignore them from now on), effectively taking the quad
; word result modulo 2^31. Now we finish the job, producing a result
; modulo 2^31-1

add si,cx ; add q to 2 low words
adc bx,di ; now BX:SI = r
; stash result back for next time a random number is asked for
mov WORD PTR [seed+2],bx
mov WORD PTR [seed],si
mov ax,si ;pass back result in DX:AX
mov dx,bx
sub si,bx
mov WORD PTR [seed_diff],si
; restore caller's registers
pop di
pop si
ret
_newrand ENDP

_newsrand PROC NEAR
PUBLIC _newsrand
push bp
mov bp,sp

mov ax,WORD PTR [bp+4]
mov dx,WORD PTR [bp+6]
mov WORD PTR [seed+2],dx
mov WORD PTR [seed],ax
sub ax,dx
mov WORD PTR [seed_diff],ax

pop bp
ret
_newsrand ENDP
_TEXT ENDS
END


;William M. Grove | Lord, grant me the serenity to accept the things I
;Psychology Dept. | cannot change, the courage to change the things I can
;U. of Minnesota | and the wisdom to hide the bodies of those I had to
; | kill because they pissed me off.


  3 Responses to “Category : Recently Uploaded Files
Archive   : 80XXX_94.ZIP
Filename : RANDOM5.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/