Jump to content
  • Advertisement
Sign in to follow this  

Assembly: How do I seed this random number generator?

This topic is 4957 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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

	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
	mov	S1, dx
	mov	S0, ax
Random	ENDP

Share this post

Link to post
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 this post

Link to post
Share on other sites

public Seed:Dword
Seed dd 0 ;seed <== change to change the seed of the random function.
mov word ptr [Seed], 0010h ;loword
mov word ptr [Seed+2], 0005h ;hiword
;makes 00050010h

Share this post

Link to post
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 this post

Link to post
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 this post

Link to post
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 this post

Link to post
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]

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!