/* TA-BOT:MAILTO your.email@marquette.edu your.partners.email@marquette.edu */ /* Main program template, including getInt, for ARM Playground 3.2 */ /* Marquette University 2019, Department of Computer Science */ #include /* Main program starts here. Put nothing before _main_:. */ .section .text .globl _main_ _main_: /* Function prolog. */ /* Sets up environment for user program to execute. */ /* Push O/S state on Stack. */ push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} sub sp, sp, #32 /* Make stack frame. */ /* Function prolog ends. */ /* Start your program. */ loop: bl getInt cmp r1, #0 bne done bl fact mov r1, r0 ldr r0, =RESULT bl kprintf b loop fact: push {r1, lr} mov r1, r0 cmp r0, #1 bgt fnext b freturn fnext: sub r0, r0, #1 bl fact bl printr mul r0, r0, r1 freturn: pop {r1, lr} // Alt: pop {r1, pc} bx lr printr: push {r0, r1, lr} mov r2, r1 mov r1, r0 ldr r0, =printr0r1 bl kprintf pop {r0, r1, lr} bx lr /* End of your program. */ /* Function epilogue. */ /* Restores the environment from the O/S. */ done: add sp, sp, #32 /* Destroy stack frame. */ /* Pop O/S state from stack.*/ pop {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} bx lr /* Return to O/S. */ /* getInt function returns positive and negative integers */ /* read in as ASCII characters representing base-10 values. */ /* Returns: */ /* r0 = integer */ /* r1 = End Of File (EOF) flag, 1 (true) or 0 (false). */ #define TOTAL r4 #define DIGIT r5 #define SIGN r6 #define SAW_EOF r7 getInt: push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} mov r0, #'?' /* Print a friendly "? " prompt. */ bl putchar mov r0, #' ' bl putchar mov TOTAL, #0 /* Initialize variables */ mov SIGN, #0 mov SAW_EOF, #0 bl getchar /* Get first character */ cmp r0, #'-' /* IF it is a minus sign, */ bne gi2 /* THEN set SIGN = 1, */ mov SIGN, #1 /* ELSE jump into main loop. */ bl putchar /* Echo minus sign. */ giloop: bl getchar /* Get first possible digit. */ gi2: cmp r0, #4 /* If EOF, exit on special case */ /* Note: 4 is the ASCII value */ /* for End of Transmission, */ /* signaled by ctrl+D. */ beq gieof cmp r0, #'\n' /* If newline, then done */ beq gidone /* reading digits. */ cmp r0, #'0' /* Check for digits between '0' */ blt giloop /* and '9'. */ cmp r0, #'9' bgt giloop /* Otherwise, ignore character */ mov DIGIT, r0 bl putchar /* Echo digit */ sub r0, DIGIT, #'0' /* Horner's Method to calculate */ mov r1, #10 /* value of number */ mul TOTAL, TOTAL, r1 add TOTAL, TOTAL, r0 b giloop gieof: mov SAW_EOF, #1 /* Special case EOF flag = true */ gidone: cmp SIGN, #1 /* IF sign = 1, subtract total */ bne gid2 /* from zero to get negative */ mov r1, #0 sub TOTAL, r1, TOTAL gid2: mov r0, #'\r' /* Echo newline and carriage return */ bl putchar mov r0, #'\n' bl putchar mov r0, TOTAL /* Stage return values */ mov r1, SAW_EOF pop {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} bx lr /* Return to caller */ /* .data section is for non-code entities, like format strings. */ /* Use .asciz, which tells the assembler to terminate the */ /* string with a null character (zero in ASCII) */ .section .data hello: .asciz "Factorial Calculator\r\n" RESULT: .asciz "Result: %d\r\n" printr0r1: .asciz "R0: %d, R1: %d\r\n"