2010-10-15 111 views
0

我需要一個用nasm編寫的隨機數生成器函數。 我很抱歉問,但我找不到任何!nasm隨機數生成器函數

+0

請參閱:http://stackoverflow.com/questions/90184/pseudo-random-generator-assembler – pinichi 2010-10-15 11:33:19

回答

1

在許多情況下rdtsc一個呼叫就足夠了。無論如何,這取決於你的需求。當你需要一個很小的隨機數很難:rdtsc % N,或者作爲其他情況下更復雜算法的種子。

1

除此之外,Agner Fog有一個用匯編編寫的隨機數發生器,請參閱here

0
; 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 
0

您好此功能使用的是這樣caled線性同餘發生器 (LCG)算法和參數是由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 

_rand的C模擬是一樣的東西

static unsigned long int next = 1; 
int _rand(void) 
{ 
    next = 1103515245 * next + 12345; 
    return next % 32768; 
} 

,並呼籲_srand的結果是一樣的 ,如果你會叫

srand(time(NULL)); 

在C.範圍生成的數字是[0,32767]。