BL-Anweisung ARM - Wie funktioniert es
Ich bin Lern-ARM-Assembly, und ich bin stuck on something right now.
Weiß ich über den Link Registrieren, der, wenn ich bin nicht falsch, enthält die Adresse zurück, wenn ein Funktionsaufruf abgeschlossen ist.
Also wenn wir sowas haben (aus der ARM-Dokumentation):
0 | here
1 | B there
2 |
3 | CMP R1, #0
4 | BEQ anotherfunc
5 |
6 | BL sub+rom ; Call subroutine at computed address.
So, wenn wir denken, der die Spalte auf der linken Seite, wie die Adresse der Anweisung, dann nach B gibt es auf Adresse 1, werden die Link-Register enthält den Wert 1 richtig?
Dann geht das Programm zu der Methode gibt und dann verwendet Sie den Wert der Link-Register zu wissen, wo, um zurückzukehren.
Wenn wir Sie überspringen, um die Adresse 6 jetzt, wo ich bin stecken, wir wissen, was BL kopiert die Adresse der nächsten Anweisung in lr (r14, der link-register).
So, jetzt würde es kopieren Sie die Adresse der sub, die einem Unterprogramm (was ist ein Unterprogramm??) + rom (was ist eine Zahl?) oder die Adresse von sub+rom (ich weiß nicht, was dies sein könnte).
Aber im Allgemeinen, wenn müssten wir BL? Warum wollen wir es im Beispiel oben? Kann mir jemand ein Beispiel wo wir es wirklich brauchen?
Dank!
- "Wann müssten wir BL?" Wenn Sie eine Funktion schreiben, die aufgerufen werden können, die aus mehr als einem Ort wird es brauchen, um zu wissen, wo es zurückgeben sollte, das ist, was das link-register wird verwendet für. Und der link registrieren, um die richtige Adresse, um zu Ihnen zurückzukehren verwenden Sie die
BL
Unterricht.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es scheint, es ist ein wenig Verwirrung. Hier ist eine Erklärung :
Den
B
Anweisung verzweigen. Er springt zu einem anderen Unterricht, und es gibt kein zurück erwartet. Das Link Register (LR) ist nicht berührt.Den
BL
Anweisung verzweigen, sondern auch link. LR geladen wird mit der Adresse der Instruktion nachBL
im Speicher, nicht die Anweisung ausgeführt, die nachBL
. Es wird dann möglich sein, die Rückkehr aus der Verzweigung mit LR.Beispiel :
Wenn Sie möchten, rufen Sie eine andere Funktion innerhalb einer Funktion, LR überschrieben werden, so dass Sie nicht in der Lage sein, um zurückzukehren. Die gemeinsame Lösung ist das speichern LR auf den stack mit
PUSH {LR}
, und stellen Sie Sie vor der Rückkehr mitPOP {LR}
. Sie können sogar wiederherstellen und zurück in einem einzigenPOP {PC}
: dies wird zur Wiederherstellung der Wert von LR, aber in der Programm-Zähler, effektiv die Rückgabe der Funktion.call/ret
push-pop-return-Adressen auf dem stack. Ich denke, ISAs, die über einen link registrieren, wie ARM, machen nicht-Blatt-Funktionen manuell abspeichern? Tatsächlich, ich habe gerade überprüft, die für mich auf godbolt: goo.gl/jgnt0T.push {r3, lr} ... pop {r3, pc}
. Also ich denker3
ist der stack-pointer. Nette, dass Sie einfach nur pop in den PC. Ich habe immer noch keine Ahnung, was sich die meisten PowerPC-asm für triviale nicht-tailcall Fall nicht, da PPC eselsbrücken scheinen viel schwieriger, herauszufinden, von Kontext / ohne Lesen docs.AND pc, pc, r2
(edit: eigentlich veraltet). Über Ihre check auf godbolt ... Eigentlich, r3 ist auch gar nicht der stack-pointer (es ist sp, alias r13). Ich habe keine Ahnung, warum GCC push r3. Per Konvention r3 ist flüchtig. Wenn Siefoo(int i)
undreturn i;
es nutzt r4 (nicht flüchtig), die Sinn machen.pop
Unterricht. Ich wusste gar nicht, dass war ein Liste Register zum push/pop. Ich dachte, du hast zu wählen, die register, die als stack-pointer, so könnten Sie es für Ihre eigene stack-Datenstrukturen oder so etwas. (Ich möchte nicht schreiben, arm-asm, ich habe gerade auch mal versuchen, es zu Lesen, insb. für c++ - std:atomic-code zu sehen, was auf eine schwach bestellt ISA). x86-Einzel-byte-Anweisungen fürpush reg
, so dass ich noch nicht einmal dachte an die Möglichkeit, eine variable-sized-push oder pop.lr
für mein test-code: Es ist die Beibehaltung der stack-ausgerichtet an einer 8B Grenze. Auch interessant: stackoverflow.com/questions/27693979/...