2017-06-30 7 views
0

Ich versuche, den Benutzer für zwei Ganzzahlen aufgefordert, und drucken Sie dann die Summe dieser beiden Ganzzahlen. Ich habe herausgefunden, wie man eine einzelne ganze Zahl, n, druckt, aber ich kann die zweite ganze Zahl, m, nicht drucken.Hinzufügen und Drucken von zwei Zahlen in ARM-Assembly

Wenn ich diesen Code ausführen, funktioniert es wie erwartet, außer dass es nur den Wert von n druckt.

Hier sind die Schritte und mein Code:

/* 1. Prompt the user to enter an integer 
* 2. Read an integer from the keyboard into memory 
* 3. Prompt the user to enter another integer 
* 4. Read an integer from the keyboard into memory 
* 5. Load the two integers into CPU registers 
* 6. Add them together 
* 7. Print the result 
*/ 

      .data 
    prompt: .asciz "Enter a number: " @ user prompt 
      .align 2 
    sformat:.asciz "%d"    @ Format string for reading an int with scanf 
      .align 2 
    pformat:.asciz "The sum is: %d\n" @ Format string for printf 
      .align 2 
    n:  .word 0     @ int n = 0 
    m:  .word 0     @ int m = 0 

      .text 
      .global main 
    main: stmfd sp!, {lr}  @ push lr onto stack 

      @ printf("Enter a number: ") 
      ldr  r0, =prompt 
      bl  printf 

      @ scanf("%d\0", &n) 
      ldr  r0, =sformat @ load address of format string 
      ldr  r1, =n   @ load address of int n variable 
      bl  scanf   @ call scanf("%d", &n) 

      @ printf("Enter a number: ") 
      ldr  r0, =prompt 
      bl  printf 

      @ scanf("%d\0" &m) 
      ldr  r0, =sformat @ load address of format string 
      ldr  r2, =m   @ load address of int m variable 
      bl  scanf   @ call scanf("%d", &m) 

      @ printf("You entered %d\n", n) 
      ldr  r0, =pformat @ load address of format string 
      ldr  r2, =m 
      ldr  r2, [r2] 
      ldr  r1, =n   @ load address of int variable 
      ldr  r1, [r1]  @ load int variable 
      add  r1, r2, r1 
      bl  printf   @ call printf("You entered %d\n", n) 

      ldmfd sp!, {lr}  @ pop lr from stack 
      mov  r0, #0   @ load return value 
      mov  pc, lr   @ return from main 
      .end 

EDIT: ich dieses Stück Code geändert r1 statt r2 zu verwenden:

@ scanf("%d\0" &m) 
ldr  r0, =sformat @ load address of format string 
ldr  r2, =m   @ load address of int m variable 
bl  scanf   @ call scanf("%d", &m) 

Dies funktioniert, aber ich verstehe nicht, warum .

+1

Bevor Sie 'scanf()' das erste Mal aufrufen, tun Sie 'ldr r1, = n'. Bevor Sie es das zweite Mal aufrufen, tun Sie 'ldr r2, = m'. Erkennst du den Unterschied? – EOF

+0

Ich denke schon. Ich versuche, die Adresse von m in r2 zu laden, damit ich r1 und r2 hinzufügen kann. EDIT: Ich änderte es zu r1, und jetzt funktioniert es, aber ich verstehe nicht warum. –

+0

Das ist irrelevant. Der einzige relevante Teil ist, wo 'scanf()' den Zeiger erwartet, der zu "% d" gehört. – EOF

Antwort

1

Ihr Fix funktioniert, da alle Architekturen einer bestimmten Aufrufkonvention folgen, in der Register Funktionsparameter und Rückgabewert zugeordnet sind. In diesem Fall nimmt scanf zwei Parameter an, so dass gemäß der ARM EABI calling convention der erste Parameter in r0 und der zweite in r1 wäre.