244 lines
4 KiB
Text
244 lines
4 KiB
Text
;x86-64 assembly code for Microsoft Windows
|
|
;Tested in windows 7 Enterprise Service Pack 1 64 bit
|
|
;With the AMD FX(tm)-6300 processor
|
|
;Assembled with NASM version 2.11.06
|
|
;Linked to C library with gcc version 4.9.2 (x86_64-win32-seh-rev1, Built by MinGW-W64 project)
|
|
|
|
;Assembled and linked with the following commands:
|
|
;nasm -f win64 <filename>.asm -o <filename>.obj
|
|
;gcc <filename>.obj -o <filename>
|
|
|
|
;Takes number of iterations to run RNG loop as command line parameter.
|
|
|
|
extern printf,puts,atoi,exit,time,_aligned_malloc
|
|
|
|
section .data
|
|
align 64
|
|
errmsg_argnumber: db "There should be no more than one argument.",0
|
|
align 64
|
|
errmsg_noarg: db "Number of iterations was not specified.",0
|
|
align 64
|
|
errmsg_zeroiterations: db "Zero iterations of RNG loop specified.",0
|
|
|
|
align 64
|
|
errmsg_timefail: db "Unable to retrieve calender time.",0
|
|
align 64
|
|
errmsg_mallocfail: db "Unable to allocate memory for array of random numbers.",0
|
|
|
|
align 64
|
|
fmt_random: db "The %u number generated is %d",0xa,0xd,0
|
|
|
|
align 16
|
|
multiplier: dd 214013,17405,214013,69069
|
|
align 16
|
|
addend: dd 2531011, 10395331, 13737667, 1
|
|
align 16
|
|
mask: dd 0xffffffff,0,0xffffffff,0
|
|
align 16
|
|
masklo: dd 0x7fff,0x7fff,0x7fff,0x7fff
|
|
|
|
section .bss
|
|
|
|
section .text
|
|
global main
|
|
|
|
main:
|
|
|
|
;check for argument
|
|
cmp rcx,1
|
|
jle err_noarg
|
|
|
|
;ensure that only one argument was entered
|
|
cmp rcx,2
|
|
jg err_argnumber
|
|
|
|
|
|
;get number of times to iterate get_random
|
|
mov rcx,[rdx + 8]
|
|
call atoi
|
|
|
|
|
|
;ensure that number of iterations is greater than 0
|
|
cmp rax,0
|
|
jle err_zeroiterations
|
|
mov rcx,rax
|
|
|
|
|
|
;calculate space needed for an array containing the random numbers
|
|
shl rcx,4
|
|
|
|
;move size of array into r14
|
|
mov r14,rcx
|
|
|
|
;16 byte alignment boundary
|
|
mov rdx,16
|
|
|
|
;reserve memory aligned to 16 byte boundary for array with _aligned_malloc
|
|
call _aligned_malloc
|
|
|
|
cmp rax,0
|
|
jz err_mallocfail
|
|
|
|
;pointer to array in r15
|
|
mov r15,rax
|
|
|
|
|
|
;seed the RNG using time()
|
|
xor rcx,rcx
|
|
call time
|
|
|
|
;ensure that time returns valid output
|
|
cmp rax,-1
|
|
jz err_timefail
|
|
|
|
|
|
;pointer to array of random numbers in r15
|
|
;address of end of array at in r14
|
|
;states stored in xmm0
|
|
|
|
;calculate address of end of array in r14
|
|
add r14,r15
|
|
|
|
;load seed,seed+1,seed,seed+1 into xmm0
|
|
lea rbx,[rax - 1]
|
|
shl rax,32
|
|
or rax,rbx
|
|
|
|
movq xmm0,rax
|
|
vpslldq xmm1,xmm0,8
|
|
vpor xmm0,xmm0,xmm1
|
|
|
|
|
|
;pointer to array of random numbers in r15
|
|
;address of end of array in r14
|
|
;current address in array in rdi
|
|
;current states in xmm0
|
|
;multiplier in xmm1
|
|
;addened in xmm2
|
|
;mask in xmm3
|
|
;masklo in xmm4
|
|
;split seed in xmm5
|
|
;current set of random numbers in xmm6
|
|
|
|
;prepare random number generator
|
|
|
|
mov rdi,r15
|
|
|
|
vmovdqa xmm1,[multiplier]
|
|
vmovdqa xmm2,[addend]
|
|
vmovdqa xmm3,[mask]
|
|
vmovdqa xmm4,[masklo]
|
|
|
|
|
|
get_random:
|
|
|
|
;arrange order of current states to 2,3,0,1 and store in split seed
|
|
vpshufd xmm5,xmm0,10110001b
|
|
|
|
;multiply current states by multiplier
|
|
vpmulld xmm0,xmm0,xmm1
|
|
|
|
;set order of multiplier to 2,3,0,1
|
|
vpshufd xmm1,xmm1,10110001b
|
|
|
|
;multiply split seed by multiplier
|
|
vpmulld xmm5,xmm5,xmm1
|
|
|
|
;and current states with mask
|
|
vpand xmm0,xmm0,xmm3
|
|
|
|
;and current split seed with mask
|
|
vpand xmm5,xmm5,xmm3
|
|
|
|
;set order of split seed to 2,3,0,1
|
|
vpshufd xmm5,xmm5,10110001b
|
|
|
|
;or current states with split seed
|
|
vpor xmm0,xmm0,xmm5
|
|
|
|
;add adder to current states
|
|
vpaddd xmm0,xmm0,xmm2
|
|
|
|
|
|
;shift vector right by two bytes
|
|
vpsrldq xmm6,xmm0,2
|
|
|
|
;and each state with 0x7fff
|
|
vpand xmm6,xmm6,xmm4
|
|
|
|
vmovdqa [rdi],xmm6
|
|
|
|
add rdi,16
|
|
cmp rdi,r14
|
|
jl get_random
|
|
|
|
|
|
;pointer to array of random numbers in r15
|
|
;address of end of array in r14
|
|
;current address in array in rdi
|
|
;array index in rsi
|
|
|
|
|
|
xor rsi,rsi
|
|
mov rdi,r15
|
|
|
|
print_random:
|
|
|
|
mov rcx,fmt_random
|
|
mov rdx,rsi
|
|
mov r8d,[rdi]
|
|
call printf
|
|
|
|
add rsi,1
|
|
add rdi,4
|
|
cmp rdi,r14
|
|
jl print_random
|
|
|
|
xor rcx,rcx
|
|
call exit
|
|
|
|
|
|
;;;;;;;;;;ERROR MESSAGES;;;;;;;;;;;;;;;;
|
|
|
|
err_argnumber:
|
|
|
|
mov rcx,errmsg_argnumber
|
|
call puts
|
|
|
|
jmp exit_one
|
|
|
|
|
|
err_noarg:
|
|
|
|
mov rcx,errmsg_noarg
|
|
call puts
|
|
|
|
jmp exit_one
|
|
|
|
|
|
err_zeroiterations:
|
|
|
|
mov rcx,errmsg_zeroiterations
|
|
call puts
|
|
|
|
jmp exit_one
|
|
|
|
|
|
err_timefail:
|
|
|
|
mov rcx,errmsg_timefail
|
|
call puts
|
|
|
|
jmp exit_one
|
|
|
|
|
|
err_mallocfail:
|
|
|
|
mov rcx,errmsg_mallocfail
|
|
call puts
|
|
|
|
|
|
exit_one:
|
|
|
|
mov rcx,1
|
|
call exit
|