Simple random number generation with MASM32
29 Nov 2012Here’s a little tid-bit that I’d like to make note of. In a previous MASM32 windows development tutorial, I needed a random number generator and was able to dig this one up from the archives.
First of all, you need to make sure we’re using the 586 instruction set - at least!
; minimum instruction set requirement
.586
Shortly, it will become clear why we need the 586 instruction set. To support the random number generator, we need a bit of state in the shape of two double-words.
; calculation state
prng_x DD 0
; current seed
prng_a DD 100711433
These two variables allow the random number generator to know where it’s up to for the next iteration. Changing the initial seed of course will change the sequence of random values that are produced by this routine. The actual function that produces the random number look like this:
PrngGet PROC range:DWORD
; count the number of cycles since
; the machine has been reset
rdtsc
; accumulate the value in eax and manage
; any carry-spill into the x state var
adc eax, edx
adc eax, prng_x
; multiply this calculation by the seed
mul prng_a
; manage the spill into the x state var
adc eax, edx
mov prng_x, eax
; put the calculation in range of what
; was requested
mul range
; ranged-random value in eax
mov eax, edx
ret
PrngGet ENDP
There it is. That first instruction RDTSC is what we need to turn the 586 instruction set on for. This mnemonic stands for Read Time-Stamp Counter. It will take the number of cycles since the machine has been reset and put this count into the EDX
:EAX
pair (as the time stamp counter is a 64bit value). From there some calculations are performed to ensure the consistency of state between random value retrieves and also capping to the requested range.
Simple and it works too!