Ich verstehe, dass ich das Link-Register zu Beginn eines Funktionsaufrufs drücken muss, und diesen Wert vor dem Zurückgeben an den Programmcouter abrufen, damit die Ausführung einen von wo vor dem Funktionsaufruf ausführen kann.ARM: Warum muss ich bei Funktionsaufrufen zwei Register drücken/öffnen?
Was ich nicht verstehe ist, warum die meisten Leute dies tun, indem sie dem Push/Pop ein zusätzliches Register hinzufügen. Zum Beispiel:
push {ip, lr}
...
pop {ip, pc}
Zum Beispiel, hier ist eine Hallo Welt in ARM, zur Verfügung gestellt von der official ARM blog:
.syntax unified
@ --------------------------------
.global main
main:
@ Stack the return address (lr) in addition to a dummy register (ip) to
@ keep the stack 8-byte aligned.
push {ip, lr}
@ Load the argument and perform the call. This is like 'printf("...")' in C.
ldr r0, =message
bl printf
@ Exit from 'main'. This is like 'return 0' in C.
mov r0, #0 @ Return 0.
@ Pop the dummy ip to reverse our alignment fix, and pop the original lr
@ value directly into pc — the Program Counter — to return.
pop {ip, pc}
@ --------------------------------
@ Data for the printf calls. The GNU assembler's ".asciz" directive
@ automatically adds a NULL character termination.
message:
.asciz "Hello, world.\n"
Frage 1: Was ist der Grund für das "Dummy-Register" ist, wie sie es nennen ? Warum nicht einfach {lr} und Pop {pc} drücken? Sie sagen, es ist der Stapel 8-Byte ausgerichtet zu halten, aber ist nicht der Stapel 4-Byte ausgerichtet?
Frage 2: Welche Register ist "ip" (das heißt, r7 oder was?)
Ich bin mit einem ARM-Blog-Post verbunden, wo sie dieses Zwei-Register-Muster empfehlen. Bitte schau es dir an, dort ist ein Code. –
Verwendung von Links wird auf SO abgeraten, weil der Link nicht so lange dauern wie die Frage (und/oder sie einfach die Frage entfernen, weil sie Links verwendet, anstatt die Diskussion hier zu haben). –
Ahh, also der Link beantwortet Ihre Frage. Sie dürfen diese Antwort selbst veröffentlichen. und schließe diese Frage aus. –