Ich glaube, ich verstehe, wie der Linux x86-64 ABI Register und Stack verwendet, um Parameter an eine Funktion zu übergeben (cf. previous ABI discussion). Was mich verwirrt, ist, ob/welche Register während eines Funktionsaufrufs erhalten bleiben sollen. Das heißt, welche Register werden garantiert nicht verfälscht?Welche Register werden durch einen Linux x86-64 Funktionsaufruf erhalten
Antwort
ist die komplette Tabelle der Register und deren Nutzung aus der Dokumentation [PDF Link]:
r12
, r13
, r14
, r15
, rbx
, rsp
, rbp
sind die Angerufene-gesicherten Register - sie In der Spalte "Bei Funktionsaufrufen beibehalten" muss ein "Ja" stehen.
Der ABI legt fest, was eine standardkonforme Software erwarten darf. Es ist in erster Linie für Autoren von Compilern, Linkern und anderen Sprachverarbeitungssoftware geschrieben. Diese Autoren möchten, dass ihr Compiler Code erzeugt, der ordnungsgemäß mit Code funktioniert, der von demselben (oder einem anderen) Compiler kompiliert wird. Sie alle müssen einer Reihe von Regeln zustimmen: Wie werden formale Argumente an Funktionen vom Aufrufer an den Aufrufer übergeben, wie werden Funktionsrückgabewerte von Aufrufer an Aufrufer zurückgegeben, welche Register bleiben über die Aufrufgrenze erhalten/scratchen/undefiniert und so auf. Beispielsweise gibt eine Regel an, dass der generierte Assemblercode für eine Funktion den Wert eines beibehaltenen Registers speichern muss, bevor der Wert geändert wird, und dass der Code den gespeicherten Wert wiederherstellen muss, bevor er an seinen Aufrufer zurückgegeben wird. Für einen Scratch-Register ist der generierte Code nicht erforderlich, um den Registerwert zu speichern und wiederherzustellen; es kann dies tun, wenn es gewünscht wird, aber standardkonforme Software darf nicht von diesem Verhalten abhängig sein (wenn dies der Fall ist, ist es keine standardkonforme Software).
Wenn Sie Assembler-Code schreiben, sind Sie verantwortlich für das Spielen nach denselben Regeln (Sie spielen die Rolle des Compilers). Das heißt, wenn Ihr Code ein auf Abruf gespeichertes Register ändert, sind Sie dafür verantwortlich, Anweisungen einzufügen, die den ursprünglichen Registerwert speichern und wiederherstellen. Wenn Ihr Assembler-Code eine externe Funktion aufruft, muss Ihr Code Argumente in der standardkonformen Weise übergeben, und es kann davon abhängen, dass bei der Rückkehr des Angerufenen beibehaltene Registerwerte tatsächlich erhalten bleiben.
Die Regeln definieren, wie standardkonforme Software auskommen kann. Es ist jedoch völlig legal, Code zu schreiben (oder zu generieren), der nach diesen Regeln nicht spielt! Compiler tun dies ständig, weil sie wissen, dass die Regeln unter bestimmten Umständen nicht eingehalten werden müssen.
Betrachten wir zum Beispiel eine C-Funktion namens foo, die erklärt sich wie folgt:
static foo(int x);
zur Compile-Zeit, der Compiler ist zu 100% sicher, dass diese Funktion nur von anderen Code in der Datei aufgerufen werden (s) es wird gerade kompiliert. Die Funktion foo
kann aufgrund der Definition dessen, was es bedeutet, statisch zu sein, nicht anders genannt werden. Da der Compiler alle Compiler des Aufrufs foo
zur Kompilierzeit kennt, kann der Compiler die gewünschte Aufrufsequenz verwenden (bis hin zu einem Aufruf überhaupt), dh den Code für foo
in die Aufrufer von foo
einbinden .
Als Autor von Assembler-Code können Sie dies auch tun.Das heißt, Sie können eine "private Vereinbarung" zwischen zwei oder mehr Routinen implementieren, solange diese Vereinbarung nicht die Erwartungen einer standardkonformen Software stört oder verletzt.
- 1. Welche Variablen können durch den Funktionsaufruf beeinflusst werden
- 2. kann ng-Klasse durch Funktionsaufruf gesetzt werden
- 3. Linux Kernel Betriebssystem Register
- 4. C: Stack Element durch einen Funktionsaufruf überschrieben
- 5. Ersetze eine href durch einen js Funktionsaufruf
- 6. Inline Assembler: Welche Scratch-Register können verwendet werden?
- 7. Hinzufügen von Elementen zu einem Array durch einen Funktionsaufruf
- 8. Wie man einen Funktionsaufruf "unterbricht"?
- 9. R: programmgesteuert einen Funktionsaufruf erstellen
- 10. Assembly - Übergeben von Parametern an einen Funktionsaufruf
- 11. Montageanleitung mov Register, [Register] [Register]
- 12. So finden Sie, welches Projekt oder welche Datei den unsicheren Funktionsaufruf durch Warnung verwendet c4996
- 13. Welche Datenstrukturen sind im Linux-Kernel verfügbar?
- 14. Erhalten Rückgabewert von Funktionsaufruf innerhalb Lambda-Ausdruck
- 15. Kann `memset` Funktionsaufruf vom Compiler entfernt werden?
- 16. Einen Funktionsaufruf in PHP-Quellcode sicher ersetzen
- 17. einen Funktionsaufruf in einer existentiellen Typ Auflösen
- 18. Wie werden Register unter Threads geteilt?
- 19. Welche Scala-Funktionen werden intern durch Reflektion implementiert?
- 20. Welche Informationen könnten durch Javascript im Browser gesammelt werden?
- 21. Welche Parameter werden durch .config() und .run() in angularjs
- 22. Welche Register werden beim Auftreten eines Interrupts auf den Stapel geschoben?
- 23. Welche CPU-Register müssen am Ende einer asm-Prozedur in Delphi wiederhergestellt werden?
- 24. Werte der CPU-Register unter GNU/Linux ändern
- 25. x86 Assembly: Bevor Sie einen Systemaufruf unter Linux durchführen, sollten Sie alle Register speichern?
- 26. Was sollte durch einen IOC-Container gebaut werden?
- 27. Welche Register in einer Funktion sicher sind (x86)
- 28. welche Version von VM unter Linux
- 29. Erhalten Sie GCC, um ein SSE-Register in einer Funktion zu erhalten, die Inline-Asm verwendet
- 30. Wann sollte ich :: einen Funktionsaufruf weiterleiten?
Upvoted. Vielen Dank! – boneheadgeek
Was ist mit Fahnen? wie DF? – socketpair
@socketpair: DF muss vor jedem Aufruf oder jeder Rückkehr nicht gesetzt sein, so dass das Aufwärtszählverhalten ohne "cld" angenommen werden kann. Zustandsflags (wie ZF) sind call-clobed. Ich vergesse genau, was die ABI-Dokumente über FP-Rundungsmodi und Denormals-are-zero sagen. Vielleicht etwas wie wenn eine Funktion sie modifiziert, muss sie den vorherigen Zustand speichern/wiederherstellen, bevor sie zurückkehrt, aber ** nimm mein Wort für den FP Teil nicht **. –