0

我需要一个用 nasm 编写的随机数生成器函数。我很抱歉问,但我找不到任何!

4

5 回答 5

1

除其他外,Agner Fog 有一个用汇编语言编写的随机数生成器,请参见此处

于 2010-10-15T16:30:54.570 回答
1

在许多情况下,一个电话rdtsc就足够了。无论如何,这取决于您的需求。当您很少需要一个小的随机数时,它是完美的:rdtsc % N,或者作为其他情况下更复杂算法的种子。

于 2010-10-15T11:49:44.170 回答
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
于 2013-02-20T18:38:32.637 回答
0

我不了解 NASM,而且我没有按需编写代码的习惯,除非他们付钱给我。

但是,您可以研究以下算法:

于 2010-10-15T11:36:46.167 回答
0

嗨,这个函数使用的是所谓的线性同余生成器(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]。

于 2017-05-23T17:27:19.313 回答