nasm random number generator function [duplicate]
I need a random number generator function written in nasm. I'm sorry for asking, but I couldn't find any!
In many cases a call to rdtsc
is enough. Anyway, it depends on your needs. It's perfect when you need a small random number rarely: rdtsc % N
, or as seed for more complicate algorithms for other cases.
Among other things, Agner Fog has a random number generator written in assembly, see here.
I don't know NASM, and I'm not in the habit of writing code on demand, unless they pay me.
But, here are algorithms you could investigate:
- http://en.wikipedia.org/wiki/Pseudorandom_number_generator
- http://en.wikipedia.org/wiki/Mersenne_twister
- http://www.codeproject.com/KB/recipes/SimpleRNG.aspx
- http://www.xkcd.org/221/
; in case you still are looking or for the ones who do look around nowadays, here is my
; experiment on random number generation.
; I hope it will be usefull.
STRUC TIMESPEC
.tv_sec: resq 1
.tv_nsec: resq 1
ENDSTRUC
STRUC TIMEVAL
.tv_sec: resq 1
.tv_usec: resq 1
ENDSTRUC
%define tv.tv_sec tv+TIMEVAL.tv_sec
%define tv.tv_usec tv+TIMEVAL.tv_usec
%define ts.tv_sec ts+TIMESPEC.tv_sec
%define ts.tv_nsec ts+TIMESPEC.tv_nsec
NUMBERCOUNT equ 50
MAXNUMBER equ 7
NUMBERLOOPS equ 50
section .bss
array resw NUMBERCOUNT ; 20 64 bit words to store the numbers
buffer resb 1
section .data
ts: ISTRUC TIMESPEC
at TIMESPEC.tv_sec, dq 0
at TIMESPEC.tv_nsec, dq 0
IEND
tv: ISTRUC TIMEVAL
at TIMEVAL.tv_sec, dq 0
at TIMEVAL.tv_usec, dq 0
IEND
section .text
global _start
_start:
; start generating 20 random numbers between 0 and 20 both values included
; we will use the computers timer to obtain a seed and a pseudo random value
; call syscall clock_gettime for the seed
xor r8,r8 ; loops
inc r8
repeatLoop:
inc r8
push r8
xor rcx, rcx
mov rdi, array
repeat:
push rcx
push rdi
mov rsi, ts
mov rdi, 0
mov rax, SYS_CLOCK_GETTIME
syscall
mov rsi, 0
mov rdi, tv
mov rax, SYS_GETTIMEOFDAY
syscall
mov rax,[ts.tv_nsec]
mov rbx,[tv.tv_usec]
xor rdx, rdx
add rax, rbx
mov rbx, MAXNUMBER+1
div rbx
mov rax, rdx
xor rdx, rdx
mov rbx, 10
div rbx
add al,30h
shl rax, 8
mov al, dl
add al,30h
pop rdi
stosw
pop rcx
inc rcx
cmp rcx, NUMBERCOUNT
jl repeat
xor rcx, rcx
mov rsi, array
repeatGet:
xor rax, rax
lodsw
push rcx
push rsi
call WriteValue
pop rsi
pop rcx
inc rcx
cmp rcx, NUMBERCOUNT
jl repeatGet
pop r8
cmp r8,NUMBERLOOPS
jg Exit
call writeEOL
jmp repeatLoop
Exit:
call writeEOL
xor rdi, rdi
mov rax, SYS_EXIT
syscall
writeEOL:
mov al,ASCII_LF
mov byte[buffer],al
mov rsi,buffer
mov rdi,STDOUT
mov rdx, 1
mov rax,SYS_WRITE
syscall
ret
WriteValue:
cmp ah,"0"
jne writeDecimal
mov ah," "
writeDecimal:
mov byte[buffer],ah
push rax
mov rsi,buffer
mov rdi,STDOUT
mov rdx, 1
mov rax,SYS_WRITE
syscall
pop rax
writeUnit:
mov byte[buffer],al
mov rsi,buffer
mov rdi,STDOUT
mov rdx, 1
mov rax,SYS_WRITE
syscall
writeSpace:
mov al," "
mov byte[buffer],al
mov rsi,buffer
mov rdi,STDOUT
mov rdx, 1
mov rax,SYS_WRITE
syscall
ret
Hi this functions are using the so caled Linear congruential generator(LCG) algorithm, and the parameters are those used by GCC.
section .bss
next: resd 1 ; 32 bits
section .text
_rand:
mov eax, [next] ; pass next to eax for multiplication
mov ebx, 1103515245 ; the multiplier
mul ebx ; eax = eax * ebx
add eax, 12345 ; the increment
mov dword [next], eax ; update next value
mov ebx, 32768 ; the modulus
xor edx, edx ; avoid Floating point exception
div ebx ; edx now holds the random number
ret ; bye
_srand:
mov eax, 0x0d ; sys_time
mov ebx, 0x0 ; NULL
int 0x80 ; syscall
mov dword [next], eax ; initialize next
ret ; bye
the C analog of _rand is something like
static unsigned long int next = 1;
int _rand( void )
{
next = 1103515245 * next + 12345;
return next % 32768;
}
and the result of calling _srand is the same as if you would call
srand( time( NULL ));
in C. The range of generated numbers is [0, 32767].
精彩评论