%include "CONSTANTS.h" RNG_A equ 1103515245 RNG_C equ 12345 RNG_M equ 4000000x section .data RNG_SEED: dq 1 randTestFMT: db `call %d = %d\n`,0 ;randRangeFMT: db `1D%d = %d\n`,0 randInRangeFMT: db `%d\n`,0 section .bss section .text global main main: main_done: ; seed the RNG mov rdi, 0 mov rax, 100 syscall mov [RNG_SEED], rax ;mov rdi, 20 ;call RAND_TEST mov rdi, 10 mov rsi, 1 mov rdx, 20 call SIMPLE_RANGE_TEST jmp Exit SIMPLE_RANGE_TEST: ; this function will generage a number of values in a gvien range ; rdi will hold the number (n) of elements to generate ; rsi will hold the low value for the range ; rdx will hold the high value for the range ; r12 will be the low value ; r13 will be used for the range ; r14 will be the lcv ; preamble push rbp mov rbp, rsp push r12 push r13 push r14 push rdi ; save n ; r12 = low mov r12, rsi ; range = high - low +1 mov r13, rdx sub r13, rsi inc r13 ; i = 0 mov r14, 0 RANGE_TEST_START: ; while i < n cmp r14, [rsp] je RANGE_TEST_DONE ; cout << RandInRange(range, low) mov rdi, r13 mov rsi, r12 call RAND_IN_RANGE mov rdi, randInRangeFMT mov rsi, rax call CallPrintf ; i++ inc r14 jmp RANGE_TEST_START RANGE_TEST_DONE: ; epilogue pop rdi pop r14 pop r13 pop r12 pop rbp ret RAND_IN_RANGE: ; this function will generate a random value in a range. ; rdi will hold the range size ; rsi will hold the min vlaue ; return the value in rax ; rax = rand() % rdi + rsi ; we will save rsi and rdi just to make sure we can. ; prefix push rbp mov rbp, rsp push rsi ; the min value push rdi ; the range size call RAND ; rax will no hold the random number mov rdx, 0 ; rax % range pop r8 ; load the value of range size div r8 ; rax + min pop rax ; load the minimum value add rax, rdx ; epilogue pop rbp ret RAND_TEST: ; this function will call the rand number generator a gvien number of times ; input: in rdi will be the number of times to call rand ; output: none ; not needed, but I want to use R12 as my LCV so I need to save it. ; not needed, but I want to use R13 as the limit ; prefix push rbp mov rbp, rsp push r12 push r13 ; rdi might be wiped out in a function call, so move this to r13 mov r13, rdi ; i = 0 mov r12, 0 ; while i < n TOP_OF_RAND_TEST_LOOP: cmp r12, r13 je OUT_OF_RAND_TEST_LOOP call RAND mov rdx, rax mov rsi, r12 mov rdi, randTestFMT call CallPrintf ; cout << i << " " << rand() << endl ; ++i inc r12 jmp TOP_OF_RAND_TEST_LOOP OUT_OF_RAND_TEST_LOOP: ; epilogue pop r13 pop r12 pop rbp ret RAND: ; no input parameters ; the result will be returned in rax ; this is a leaf routine, no need to build an AR ; load the previous seed mov rax, qword [RNG_SEED] ; multiply this by A mov rdx, 0 mov r10, RNG_A mul r10 ; add c to it add rax, RNG_C ; mod by m mov rdx, 0 mov r10, RNG_M div r10 ; save the in the global seed mov rax, rdx mov qword[RNG_SEED], rax ; return it in rax ret