Look below for a later version.
Thats SO much shorter than Mersenne-Twister implementations in assembly Ive seen!
Ralph,
Note that this algo is for seeding a random number generator, it is not a random number generator in itself.
LOCAL var1 :QWORD
fill the stack with garbage after calling QueryPerformanceCounter.
:biggrin:
Perhaps you could elaborate.
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
in your example, r10 = 0 after the QueryPerformanceCounter. With the stack everything is fine :-), because the result is immediately recorded there.
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
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
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤