Assembly: How do I seed this random number generator?

Started by
5 comments, last by Googler 19 years, 5 months ago
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
	adc	dx, 0
Store:
	mov	S1, dx
	mov	S0, ax
	ret
Random	ENDP
	END

Advertisement
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.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
.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

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.


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?
Free Mac Mini (I know, I'm a tool)

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.
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.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

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]

This topic is closed to new replies.

Advertisement