Sign in to follow this  
Googler

Assembly: How do I seed this random number generator?

Recommended Posts

Googler    122
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

Share this post


Link to post
Share on other sites
Extrarius    1412
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
Washu    7829

.data
public Seed:Dword
Seed dd 0 ;seed <== change to change the seed of the random function.
.code
;aka
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
igni ferroque    415

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
Googler    122

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
Washu    7829
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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this