%include "CONSTANTS.h" A EQU 1103515245 M EQU 70000000h C EQU 12345 section .data RNG_SEED: dq 1 ; the x in the LCG random number generator RAND_TEST_FMT: db `%d %d\n`,0 RANGE_FMT: db `Range %d to %d -> %d\n`,0 ArrayValueFmt: db `A[%d]= %d\n`,0 section .bss section .text global main main: mov rdi, 20 mov rsi, 1000 call TEST_ROLL ;mov rdi, format1 ;mov rsi, -1 ;call CallPrintf ;mov rdi, 5 ;call TEST_RAND ;mov r12, 0 ;.top: ;cmp r12, 20 ;je .done ; ; mov rdi, 3 ; mov rsi, 22 ; call RAND_IN_RANGE ; ; mov rdi, RANGE_FMT ; mov rsi, 3 ; mov rdx, 22 ; mov rcx, rax ; call CallPrintf ; inc r12 ; jmp .top ;.done: jmp Exit ; rdi will hold the size of the die 0 to rdi -1 ; rsi will hold the number of trials to execute ; TestRoll(int maxSides, int trials) ; int counts[maxSides] ; ; for(i =0; i << maxSides; ++i) { ; counts[i] = 0 ; } ; ; for(i =0; i << trials; ++i) { ; counts[randInRange(0, max) ] ++ ; } ; ; for(i =0; i << maxSides; ++i) { ; cout << i << " " << counts[i] << endl ; } TEST_ROLL: push rbp mov rbp, rsp ; declare the array ; I added this line in debugging. Probably not needed. mov rdx, 0 mov rax,rdi mov r8, 8 mul r8 sub rsp, rax ; temporarly store the base address of the array in rax mov rax, rsp push r12 push r13 push r14 push r15 ; r12 will hold maxvalue or max sides mov r12, rdi ; r13 will hold the LCV ; r14 will hold the base address of the array ; mov r14, rsp ; add r14, 32 mov r14 , rax ; r15 will hold the number of trials mov r15, rsi ;for i =0; i < max; ++i) array[i] = 0 mov r13, 0 InitLoopTop: ; We had an arry out of bounds because we had the wrong variable here ; r15 holds the number of trials ; r12 holds the number of sides ;cmp r13, r15 cmp r13, r12 je .InitLoopDone mov qword [r14 +r13*8], 0 inc r13 jmp InitLoopTop .InitLoopDone: ; call the RNG a bunch of times. ;for i =0; i < max; ++i) cout << i << array[i] mov r13, 0 PrintLoopTop: ; We had an arry out of bounds because we had the wrong variable here cmp r13, r12 je .PrintLoopDone mov rdi, ArrayValueFmt mov rsi, r13 mov rdx, [r14 +r13*8] call CallPrintf inc r13 jmp PrintLoopTop .PrintLoopDone: TestRollDone: pop r15 pop r14 pop r13 pop r12 mov rsp, rbp pop rbp ret TEST_RAND_IN_RANGE: ; void TestRandInRange(long low, long high, long iterations) { ; if low >= high ; return ; else ; range = high-low ; long counts[range] ; ; for(int i =0; i < range; ++i) { ; counts[i] = 0 ; } ; ; for(int i =0; i < iterations; ++i) { ; counts[RandInRange(low,high)-low]++ ; } ; ; for(int i =0; i < range; ++i) { ; cout << i+low << " " << counts[i]; ; } ;} ; ; register dictionary ; r12 will hold the base address of counts push rbp mov rbp, rsp ; r12 will be the base address of the array ; r13 will be the lcv push r12 push r13 ; restore preserveds pop r13 pop r12 ; restore the stack pop rbp ret ; this routine will compute a random value in a given range. ; long RAND_IN_RANGE(long low, long high) { ; range = high - low ; long value = low + rand() % range ; return value ;} ; RAND_IN_RANGE: push rbp mov rbp, rsp ; r12 will be used for low push r12 RANGE_OFFSET: equ -16 ; local variable for range ; range will be at rbp-16 add rsp, -8 mov r12, rdi ; value = low + rand() % range ; range = high -low mov rax, rsi sub rax, rdi mov [rbp + RANGE_OFFSET], rax call RAND ; find %range mov rdx, 0 div qword [rbp - 16] mov rax, rdx ; add low add rax, rdi ; EXIT STUFF add rsp, 8 pop r12 pop rbp ret ; this routine will test the rand function. ; It has one parameter, n which is positive ; ; void TEST_RAND(long n) { ; for(long i =0; i < n; ++i) { ; cout << i << " " << n << endl; ; } ; } ; Register Use ; RAX will be used for function call return value (RAND) ; and also for the cout statement (return value) ; rdi will be used for printf ; will also contain n on call ; r12 will be used to hold n ; rsi will be used for printf ; rdx will be used for printf TEST_RAND: push rbp mov rbp, rsp ; r12 will be used to hold n push r12 mov r12, rdi ; r8 will be the LCV ; for i = 0; i < n ; ++i mov r8, 0 top: cmp r8, r12 je .done push r8 call RAND pop r8 ; cout << i << " " << rand() mov rdi, RAND_TEST_FMT mov rdx, rax mov rsi, r8 push r8 ; save r8 across the function call call CallPrintf ; restore r8 pop r8 inc r8 jmp top .done: ; restore preserveds that I used pop r12 pop rbp ret RAND: ; Xn+1 = (A * Xn + C) % M ; return Xn+1 in rax ; no parameters push rbp mov rbp, rsp mov r8, 10909910189 ; compute AX mov rax, [RNG_SEED] mov rcx, A mov rdx, 0 mul rcx ; compute AX + C add rax, C ; compute (AX + C ) % M mov rcx, M div rcx ; set up for return mov rax, rdx ; and save X for next computation mov [RNG_SEED], rax pop rbp ret