Author Topic: Random number  (Read 19410 times)

nobody

  • Guest
Random number
« on: July 21, 2009, 04:48:09 PM »
Is there a random function in NASM? I want to have a user guess a number that the pc randomly generated.

Sincerely,
                                   Mitch

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Random number
« Reply #1 on: July 21, 2009, 06:50:54 PM »
Nasm only assembles what x86(_64) implements. I vaguly recall hearing that some CPU *does* include a "random" instruction, but I can't find it. I use "rdtsc". Since it always comes up with an even number, I shift it right one to get rid of the low (always zero) bit. No way this is truely "random", since it is always increasing, but probably good enough for "guess the number". If you need something better, look into the C library "rand() and "srand()" functions - or implement it yourself.

Best,
Frank

mene mene tekel

  • Guest
Re: Random number
« Reply #2 on: July 22, 2009, 05:35:28 PM »
Hi,
take this code sippet:

segment .rdata ; *** Attributes as in 1st segment declaration ***

; *** Rounding flags for FRNDINT
rndMath     dw 0x037F         ;Default round after FINIT    (mathematische Rundung)
rndCeil     dw 0x037F|0x0800  ;Round up   to high integer   (Gaussklammer oben)
rndFloor    dw 0x037F|0x0400  ;Round down to low  integer   (Gaussklammer unten)
rndTrunc    dw 0x037F|0x0C00  ;Truncate towards zero int    (Nachkommawert abschneiden)

; *** Random Generator: linear congruential generator (LCG)
randConst   dd 0x00003039     ;ANSI C: Addition constant:   =      12345
randMult    dd 0x41C64E6D     ;ANSI C: Multiplicator:       = 1103515245
randShift   dd 0x00000000     ;ANSI C: No shift necessary
randMask    dd 0x7FFFFFFF     ;ANSI C: Take bits 0..30
randValue   dd 0x3C6EF35F     ;Initial value & result container

segment .code  ; *** Attributes as in 1st segment declaration ***

; ---------------------------------------------------------------------------
; ---                         R N D   D O U B L E                         ---
; ---------------------------------------------------------------------------
;
; rndDoubleFunc is a LCG random number generator based on ANSI C specification.
; This floating point versions returns values 0 <= rnd <= 1
;
; DOUBLE rndDoubleFunc()
; DOUBLE seedDoubleFunc()
;
; ---------------------------------------------------------------------------

rndDoubleFunc:
            push  edx                           ;Save edx register
            mov   eax,  [randValue]             ;Calculate
            mov   edx,  [randMult]              ; R(n+1) :=
            mul   edx                           ; (R(n)*MULT + CONST)
            add   eax,  [randConst]             ; MOD MASK
            and   eax,  [randMask]              ; in CPU register and
            mov   dword [randValue],   eax      ; save back R(n+1)
            pop   edx                           ;Restore edx regsiter
            fild  dword [randValue]             ;Normalize
            fidiv dword [randMask]              ; to ONE in FPU
.end:       ret                                 ;Return

seedDoubleFunc:
            push  edx                           ;Save edx register
            rdtsc                               ;Get real time clock
            and   eax,  [randMask]              ; and mask it and
            mov   dword [randValue],   eax      ; save back as R(n+1)
            pop   edx                           ;Restore edx regsiter
            fild  dword [randValue]             ;Normalize
            fidiv dword [randMask]              ; to ONE in FPU
.end:       ret                                 ;Return


Seed is initializing by timer
Rnd gives the next from series

Martin