@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @ This program defines and uses functions div10 @ and print10. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @ Program part 1: definition of main. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .globl _start _start: mov sp, #0x100000 @initialize sp at start of program @ program preamble sub sp, sp, #20 str lr, [sp, #0] str r0, [sp, #4] str r4, [sp, #8] str r5, [sp, #12] str r6, [sp, #16] @ program main body ldr r4,=0x101f1000 @ ASCII codes stored @ at [r4] get printed mov r5, #0x7f lsl r5, r5, #8 add r5, r5, #0xff lsl r5, r5, #8 add r5, r5, #0xff lsl r5, r5, #8 add r5, r5, #0xf0 mov r6, #0 loop: cmp r6, #20 bgt program_exit mov r0, r5 bl print10 add r5, r5, #1 add r6, r6, #1 b loop @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @ Program part 2: definition of all functions. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ div10: @ div10 preamble sub sp, sp, #36 str lr, [sp, #0] str r4, [sp, #4] str r5, [sp, #8] str r6, [sp, #12] str r7, [sp, #16] str r8, [sp, #20] str r9, [sp, #24] str r10, [sp, #28] str r11, [sp, #32] @ div10 main body mov r4, r0 @ r4 = arg lsr r5, r4, #4 @ r5: lower bound lsr r6, r4, #3 @ r6: upper bound mov r7, r6 @ r7: current guess, initialized to upper bound mov r9, #10 @ r9: constant 10. div10_loop: mul r8, r7, r9 @ r8 = current guess * 10 cmp r8, #0 @ check for overflow movlt r6, r7 @ if overflow, set upper bound = guess. blt div10_next_guess cmp r8, r4 mov r10, #0 movle r10, #1 @ r10 = (10 * current guess <= arg) mov r11, #0 add r8, r8, #9 @ r8 = 10 * current guess + 9 cmp r8, #0 @ check for overflow movlt r11, #1 @ if overflow, it means that @ (10 * current guess + 9 >= arg) blt div10_check cmp r8, r4 movge r11, #1 @ r11 = (10 * current guess + 9 >= arg) div10_check: add r11, r11, r10 @ r11 = 2 if (10*guess <= arg <= 10*guess + 9) cmp r11, #2 @ if r11 == 2, we are done moveq r0, r7 @ arg/10 is r7, store at r0 mul r8, r7, r9 @ r8 = current guess * 10 subeq r1, r4, r8 @ r1 = remainder of arg/10 beq div10_exit @ exit, we have computed the results cmp r8, r4 @ compare 10*guess with arg movgt r6, r7 @ if 10>guess > arg, set upper_bound = guess movlt r5, r7 @ else set lower bound = guess div10_next_guess: add r7, r5, r6 @ guess = (lower bound + upper bound) lsr r7, r7, #1 @ guess = (lower bound + upper bound) / 2 b div10_loop div10_exit: @ div10 wrap-up ldr lr, [sp, #0] ldr r4, [sp, #4] ldr r5, [sp, #8] ldr r6, [sp, #12] ldr r7, [sp, #16] ldr r8, [sp, #20] ldr r9, [sp, #24] ldr r10, [sp, #28] ldr r11, [sp, #32] add sp, sp, #36 bx lr @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ print10: @ print10 preamble sub sp, sp, #28 str lr, [sp, #0] str r0, [sp, #4] str r1, [sp, #8] str r4, [sp, #12] str r5, [sp, #16] str r6, [sp, #20] str r7, [sp, #24] @ print10 main body ldr r4,=0x101f1000 @ ASCII codes stored @ at [r4] get printed mov r5, r0 cmp r5, #0 movlt r6, #'-' strlt r6, [r4] movlt r7, #-1 mullt r0, r5, r7 bl print10_helper @ print newline mov r5, #13 str r5, [r4] mov r5, #10 str r5, [r4] @ print_number wrap-up ldr lr, [sp, #0] ldr r0, [sp, #4] ldr r1, [sp, #8] ldr r4, [sp, #12] ldr r5, [sp, #16] ldr r6, [sp, #20] ldr r7, [sp, #24] add sp, sp, #28 bx lr @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ print10_helper: @ print10_helper preamble sub sp, sp, #28 str lr, [sp, #0] str r0, [sp, #4] str r1, [sp, #8] str r4, [sp, #12] str r5, [sp, #16] str r6, [sp, #20] str r7, [sp, #24] @ print10_helper main body ldr r4,=0x101f1000 @ ASCII codes stored @ at [r4] get printed cmp r0, #10 addlt r6, r0, #'0' strlt r6, [r4] blt print10_helper_exit bl div10 bl print10_helper add r6, r1, #'0' str r6, [r4] print10_helper_exit: @ print10_helper wrap-up ldr lr, [sp, #0] ldr r0, [sp, #4] ldr r1, [sp, #8] ldr r4, [sp, #12] ldr r5, [sp, #16] ldr r6, [sp, #20] ldr r7, [sp, #24] add sp, sp, #28 bx lr @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ print_digit: @ print_digit preamble sub sp, sp, #12 str lr, [sp, #0] str r4, [sp, #4] str r5, [sp, #8] @ print_digit main body ldr r4,=0x101f1000 @ ASCII codes stored @ at [r4] get printed cmp r0, #10 addlt r5, r0, #48 addge r5, r0, #55 str r5, [r4] @ print_digit wrap-up ldr lr, [sp, #0] ldr r4, [sp, #4] ldr r5, [sp, #8] add sp, sp, #12 bx lr @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ print_number: @ print_number preamble sub sp, sp, #24 str lr, [sp, #0] str r0, [sp, #4] str r4, [sp, #8] str r5, [sp, #12] str r6, [sp, #16] str r7, [sp, #20] @ print_number main body ldr r4,=0x101f1000 @ ASCII codes stored @ at [r4] get printed mov r5, #28 mov r6, r0 print_number_loop: cmp r5, #0 blt print_number_exit lsr r7, r6, r5 and r7, r7, #0x0000000f mov r0, r7 bl print_digit sub r5, r5, #4 b print_number_loop print_number_exit: @ print newline mov r5, #13 str r5, [r4] mov r5, #10 str r5, [r4] @ print_number wrap-up ldr lr, [sp, #0] ldr r0, [sp, #4] ldr r4, [sp, #8] ldr r5, [sp, #12] ldr r6, [sp, #16] ldr r7, [sp, #20] add sp, sp, #24 bx lr @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @ Program part 3: program exit. @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ program_exit: @ program wrap-up ldr lr, [sp, #0] ldr r0, [sp, #4] ldr r4, [sp, #8] ldr r5, [sp, #12] ldr r6, [sp, #16] add sp, sp, #20 ldr r4,=0x101f1000 mov r1, #13 str r1, [r4] mov r1, #10 str r1, [r4] mov r1, #'E' str r1, [r4] mov r1, #'N' str r1, [r4] mov r1, #'D' str r1, [r4] the_end: b the_end