News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Random seed for random algorithm example

Started by hutch--, April 13, 2018, 12:57:32 AM

Previous topic - Next topic

hutch--

Look below for a later version.

wreckItRalph

Thats SO much shorter than Mersenne-Twister implementations in assembly Ive seen!

hutch--

Ralph,

Note that this algo is for seeding a random number generator, it is not a random number generator in itself.

pinok

LOCAL var1  :QWORD

fill the stack with garbage after calling QueryPerformanceCounter.

hutch--


pinok

So?

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

include \masm32\include64\masm64rt.inc

.code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

LOCAL lcnt : QWORD

mov lcnt, 20

lbl :
   call reseed
   conout str$(rax), lf
   sub lcnt, 1
   jnz lbl

   waitkey
   .exit

   main endp

   ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

   NOSTACKFRAME

   reseed proc
   ; --------------------------------------
   ; random algorithm random seed generator
   ; --------------------------------------
   LOCAL var1 : QWORD

   mov r9, 1000; set the counter
   mov r11, 12345678; put something in r11

   @@:
   invoke QueryPerformanceCounter, addr var1; call the API
   mov rax, var1; write value in var1 to rax
   bswap rax; byte swap rax
   xor r11, rax; xor combine with r11
   sub r9, 1; decrement counter
   jnz @B; loop again if not 0

   mov rax, r11; return xorred content in rax

   ret

   reseed endp

   STACKFRAME

   ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

   end

pinok

in your example, r10 = 0 after the QueryPerformanceCounter. With the stack everything is fine :-), because the result is immediately recorded there.

hutch--

Here is the replacement, it worked OK when I first wrote it but Win10 keeps changing and the register usage so I changed the registers to preserved non-volatile ones but kept the algorithm identical. From Win32 help,
Quote
Return Values
If the installed hardware supports a high-resolution performance counter, the return value is nonzero.
If the installed hardware does not support a high-resolution performance counter, the return value is zero.
This is why you were getting a zero return value from QueryPerformanceCounter().
This is the output which is different every call.

-576460752291077810
-3963167672073690802
-8646629809562295986
-2161727821125492402
-2954361355542699698
504403158277841230
3602879701908742478
1729382256922616142
-936748722480717490
-4611686018415042226
-7349030166926171826
1945555039036399950
6413407344364642638
-3313804900802207410
4757771531352564046
1585267068846760270
7566047373994778958
864691128467480910
4611967493416444238
1585267068846760270
Press any key to continue...

The example.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    LOCAL lcnt  :QWORD

    mov lcnt, 20

  lbl:
    call reseed
    conout str$(rax),lf
    sub lcnt, 1
    jnz lbl

    waitkey
    .exit

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

; NOSTACKFRAME

reseed proc
  ; --------------------------------------
  ; random algorithm random seed generator
  ; --------------------------------------
    LOCAL var1  :QWORD
    USING r13,r14,r15

    SaveRegs

    lea r14, var1                           ; load the address
    mov r13, 1000                           ; set the counter
    mov r15, 12345678                       ; put something in r15

  @@:
    rcall QueryPerformanceCounter, r14      ; call the API
    mov rax, [r14]                          ; write value in var1 to rax
    bswap rax                               ; byte swap rax
    xor r15, rax                            ; xor combine with r15
    sub r13, 1                              ; decrement counter
    jnz @B                                  ; loop again if not 0

    mov rax, r15                            ; return xorred content in rax

    RestoreRegs

    ret

reseed endp

; STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end

hutch--

This is the version I use in the library.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

get_unique_seed proc
  ; ------------------------------------
  ; create a seed for a random algo that
  ; is extremely difficult to re-produce
  ; ------------------------------------
    LOCAL var1  :QWORD
    LOCAL var2  :QWORD
    LOCAL var3  :QWORD
    LOCAL var4  :QWORD
    LOCAL var5  :QWORD

    invoke QueryPerformanceCounter,ADDR var1
    invoke QueryPerformanceCounter,ADDR var2
    invoke QueryPerformanceCounter,ADDR var3
    invoke QueryPerformanceCounter,ADDR var4
    invoke QueryPerformanceCounter,ADDR var5

    mov rax, var1
    mov rcx, var2
    rol rcx, 13
    mov rdx, var3
    rol rdx, 26
    mov r10, var4
    rol r10, 39
    mov r11, var5
    rol r11, 52
    xor rax, rcx
    xor rax, rdx
    xor rax, r10
    xor rax, r11
    bswap rax

    ret

get_unique_seed endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤