0

I am trying to read several values (one at a time) with scanf in ARM Assembly. I manage to get the scanf portion working and it apparently saves the values right. But when i want to retrieve them I only get the last number right and the other ones get something else.

This is what it is giving me:

Enter a number: 1  
Enter a number: 2  
You entered: 2129322344 and 2.  

It should say You entered 1 and 2.

My code looks like this:

  .global main
  .func main

main:
  PUSH {LR}
  LDR R0, =entryMessage
  BL printf
  SUB SP, SP, #8
  LDR R0, =scanformat
  MOV R1, SP
  BL scanf        @ Number is saved in SP - 8
  LDR R0, =entryMessage
  BL printf
  ADD SP, SP, #4
  LDR R0, =scanformat
  MOV R1, SP
  BL scanf        @ Number is saved in SP - 4
  ADD SP, SP, #4  @ Restore SP to original
  SUB SP, SP, #8  @ Prepare to read SP - 8 for first number
  LDR R1, [SP]    @ Read first number
  ADD SP, SP, #4  @ Prepare to read SP - 4 for second number
  LDR R2, [SP]    @ Read second number
  ADD SP, SP, #4  @ Restore SP to original
  LDR R0, =printMessage
  BL printf
  POP {PC}

_exit:
  BX LR

.data
  entryMessage: .asciz "Enter a number: "
  scanformat: .asciz "%d"
  printMessage: .asciz "You entered: %d and %d.\n"

Can someone tell me why is it that only the last value gets read correctly?

Xavier Merino
  • 679
  • 1
  • 5
  • 19

1 Answers1

2

You ADD SP, SP, #4 before calling scanf for the second time, then the call overwrites the previous value entered. You could store them in reverse order, before loading into R1 and R2. So the stack pointer is never higher than a stored value you want to use.

main:
    PUSH {LR}
    LDR R0, =entryMessage
    BL printf

    SUB SP, SP, #4  @ Reserve space for the first number entry
    LDR R0, =scanformat
    MOV R1, SP
    BL scanf        @ Number is saved at original SP - 4

    LDR R0, =entryMessage
    BL printf

    SUB SP, SP, #4  @ Reserve space for the second number entry
    LDR R0, =scanformat
    MOV R1, SP
    BL scanf        @ Number is saved at original SP - 8

    LDR R2, [SP]    @ Read second number
    ADD SP, SP, #4  @ Prepare to read first number
    LDR R1, [SP]    @ Read first number
    ADD SP, SP, #4  @ Restore SP to original
    LDR R0, =printMessage
    BL printf

    POP {PC}
Weather Vane
  • 33,872
  • 7
  • 36
  • 56