# Assembly: How do I seed this random number generator?

## Recommended Posts

This random number generator is working like it's supposed to, but it's giving me the same sequence of numbers each time I run it because I can't figure out how to seed it. I read the author's notes ("Assumes seed has been set elsewhere as a PUBLIC double-word"), but I don't know enough to get that to work. I'm using tasm and tlink. Lemme know if you need more specific information.
;; 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
Store:
mov	S1, dx
mov	S0, ax
ret
Random	ENDP
END



##### Share on other sites
Are you declaring a variable named 'seed' anywhere? If not, it shouldn't link because it says there is such a variable and it uses it but it doesn't declare that variable.

If so, just setting the variable should seed it to whatever you want. To get different sequences each run, just set it to the time or something.

##### Share on other sites
.datapublic Seed:DwordSeed dd 0 ;seed <== change to change the seed of the random function..code;akamov word ptr [Seed], 0010h ;lowordmov word ptr [Seed+2], 0005h ;hiword;makes 00050010h

##### Share on other sites

To be able to link a routine with a high-level language, you have to put the code and data in the proper segments, which means knowing how the language declares its segments and groups. For example, Borland code segments are named _TEXT. Shared identifiers must be made PUBLIC where they are defined, and EXTRN where they are used but not defined. These identifiers appear in the .OBJ files produced by assemblers and compilers, and the linker matches them up. (A Tale of Two Assemblers)

How are you calling the code?

##### Share on other sites

To Extrarius:
Yeah, I'd like to seed it to time, I think I know how once I can get it let me (int 1Ah, right?).

To Washu:
That's what I was trying before I think. I tried it again but it's telling me there's 'extra characters on line'. I have no idea why it's telling me that though. I copied it just like you had.

To Igni:
I think I know what you mean.

EXTRN Random: NEAR (In the .CODE before the main PROC)

when I call it:
call Random

I would post my code but it's very long and only bout 70% done though it does assemble.

Anyway thanks for the quick replies. I'm gonna keep trying.

##### Share on other sites
Well, you're not supposed to take it literally, it was just "sample" code, but the public line is probably wrong. Should probably just be public seed.

##### Share on other sites
You're right :)
It works now. Thanks a bunch, I gave you a good rating.

[Edited by - Googler on November 25, 2004 12:00:18 AM]

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628366
• Total Posts
2982274

• 10
• 9
• 13
• 24
• 11