%include "CONSTANTS.h" %define DEBUG 1 extern rand extern time extern srand extern printf ; ; struct ResultT { ; int value ; int count ; long percent VALUE_OFFSET EQU 0 COUNT_OFFSET EQU 4 PCT_OFFSET EQU 8 RESULT_SIZE EQU 16 ROLLS EQU 3 SIDES EQU 6 section .data RollResult: db `%d `,0 RollSum: db ` = %d \n`,0 TimesLine: db `%2d occured %8d times or %8.4f%\n`,0 trials: dq 1000000 hundred: dq 100.00 section .bss ary: resq (ROLLS + ROLLS*SIDES ) * 2 section .text global main SYS_TIME equ 100 main: ; initialize the random number generator ; srand(time(nullptr)) mov rdi, 0 call time mov rdi, rax call srand ; for(int i =0; i <= ROLLS * SIDES; ++i) { ; int sum = 0 ; for(int j =0; j < ROLLS; ++j) ; sum += rand() % SIDES + 1 ; } ; ++ ary[sun].count; ; r12 is the outer lcv mov r12, 0 .topGenLoop: cmp r12, [trials] je .doneGenLoop ; r13 is the sum of three throws mov r13, 0 ; r14 is the inner lcv mov r14, 0 .topOneRoll: cmp r14, ROLLS je .doneWithRoll ; tmp = rand; mov rax, 0 call rand ; tmp = (tmp % sides) + 1 mov r8, SIDES mov rdx, 0 div r8 mov rax, rdx inc rax ; sum += tmp add r13, rax %ifdef DEBUG ; cout << tmp << " " mov rdi, RollResult mov rsi, rax call CallPrintf %endif inc r14 jmp .topOneRoll .doneWithRoll: %ifdef DEBUG ;cout << " = " << sum mov rdi, RollSum mov rsi, r13 call CallPrintf %endif ; you an only multiply a register by 2, 4, 8 in an address computation ; so compute the array offset in rax mov rax, RESULT_SIZE mul r13 ; ++ary[sum].count inc qword [ary + rax + COUNT_OFFSET ] inc r12 jmp .topGenLoop .doneGenLoop: ; I did not want to do strange indexing, so I will ignore ; the first rolls locations in the array ; IE for 1 die, we can never have a 0 ; for 2 die, we can never have a 0 or a 1 ; i = rolls ; ; for(i = rolls ; i <= ROLLS * SIDES; ++i) { ; float denom = static_cast trials ; float result = static_cast ary[i].count ; result /= denom ; result * = 100 ; ary[i].pct = result ; ary[i].value = i ;} mov r12, ROLLS .topCalcLoop: cmp r12, ROLLS*SIDES + 1 je .doneCalcLoop ; compute the offset mov rax, RESULT_SIZE mul r12 mov r8, rax ; xmm0 = ary[i].count/trials * 100 cvtsi2sd xmm1, [trials] cvtsi2sd xmm0, qword[ary + r8 + COUNT_OFFSET] divsd xmm0, xmm1 mulsd xmm0, [hundred] ; ary[i].value = i ; probably not needed, but I intended to sort this. mov [ary + r8 + VALUE_OFFSET], r12d ; ary[i].pct = result movsd qword [ary + r8 + PCT_OFFSET], xmm0 inc r12, jmp .topCalcLoop .doneCalcLoop: ; for(int i =rolls; i <= rolls*sides; ++i) { ; cout << ary[i].value << " " << ary[i].count << " " << ary[i].pct ;} mov r12, ROLLS .topPrintLoop: cmp r12, ROLLS * SIDES + 1 je .donePrintLoop ; compute the offset mov rax, RESULT_SIZE mul r12 mov r8, rax mov rdi, TimesLine mov rsi, [ary + r8 + VALUE_OFFSET] mov edx, dword [ary + r8 + COUNT_OFFSET] movsd xmm0, [ary + r8 + PCT_OFFSET] mov rax, 1 mov r15, rsp and rsp, -16 call printf mov rsp, r15 inc r12 jmp .topPrintLoop .donePrintLoop: .done: jmp Exit