assemblyarmcpu-registers

ARM Assembly - Why is the output printing differently?


I'm currently learning to code with ARM and was working on this assignment where I need to convert inches to feet. I believe I have everything in working order, but when it comes to printing the output on the terminal, I am not getting the results that I want. When I go to debug my code, I can see that I have implemented everything the way that I wanted and the values of the registers that I am using are what they should be, but the output ends up being different. For example, when I go to input 67 inches into my program, the output comes out to be 5 ft and -307609856 in. What am I missing? It seems like I'm messing up with the reference of the registers? Any pointers or guidance would be greatly appreciated. Thank you in advance!

.text
.global main
main:
        SUB sp, sp, #4
        STR lr, [sp]

        # provide prompt for user
        LDR r0, =prompt
        BL printf

        # read in the input
        LDR r0, =formatString
        LDR r1, =inches
        BL scanf

        # divide the input by 12 - remainder operation
        LDR r0, =inches
        LDR r0, [r0]
        MOV r1, #12
        MOV r2, #0
        MOV r3, r0

        # compare the remainder wth 12
        loop:

        CMP r3, r1
        BLT exit //if the remainder < 12, stop the comparison

        # subtract 12 from the dividend - this is the remainder
        SUB r3, r3, r1
        ADD r2, r2, #1 //tracks how many times the dividend is subtracted by 12 - this is the number of feet
        B loop

        exit:

        # print the output in units feet
        MOV r1, r2
        LDR r0, =output1
        BL printf

        # print the output in units inches
        MOV r1, r3
        LDR r0, =output2
        BL printf


        LDR lr, [sp]
        ADD sp, sp, #4
        MOV pc, lr
.data
        prompt: .asciz "enter height in inches: "
        formatString: .asciz "%d"
        inches: .word 0
        output1: .asciz "\nheight in feet is %d\n"
        output2: .asciz "height in inches is %d\n"e

I tried changing the registers for this block of code since r3 during runtime is given the value I am looking for, but it keeps resetting to the initial value of r3 rather than save the expected value

# print the output in units inches
        MOV r1, r3
        LDR r0, =output2
        BL printf

Solution

  • r0 to r3 are typically not preserved when calling functions in ARM assembly. So after your first printf, the value in r3 is trashed. Instead, try using r4 or any of the other higher numbered registers to store your inches in. (Storing and restoring r3 onto the stack is also possible, but here you have lots of spare registers).

    See for example this answer which discusses the ARM calling convention including some useful links: What registers to save in the ARM C calling convention?