Funktionsprolog und Epilog - Function prologue and epilogue
In Assembler - Sprache - Programmierung , die Funktion Prolog ist ein paar Zeilen Code zu Beginn einer Funktion, die die Vorbereitung Stapel und Register für die Verwendung innerhalb der Funktion. In ähnlicher Weise erscheint der Funktions-Epilog am Ende der Funktion und stellt den Stack und die Register in dem Zustand wieder her, in dem sie sich vor dem Aufruf der Funktion befanden.
Prolog und Epilog sind nicht Teil der Assemblersprache selbst; Sie stellen eine Konvention dar, die von Programmierern in Assemblersprache und Compilern vieler höherer Sprachen verwendet wird . Sie sind ziemlich starr und haben in jeder Funktion die gleiche Form.
Funktionsprolog und Epilog enthalten manchmal auch Code für den Pufferüberlaufschutz .
Prolog
Ein Funktionsprolog führt normalerweise die folgenden Aktionen aus, wenn die Architektur einen Basiszeiger (auch bekannt als Rahmenzeiger) und einen Stapelzeiger hat:
- Verschiebt den aktuellen Basiszeiger auf den Stack, damit er später wiederhergestellt werden kann.
- Weist den Wert des Basiszeigers der Adresse des Stack-Zeigers zu (der auf die Spitze des Stapels zeigt), sodass der Basiszeiger auf die Spitze des Stapels zeigt.
- Bewegt den Stapelzeiger weiter, indem sein Wert verringert oder erhöht wird, je nachdem, ob der Stapel nach unten oder nach oben wächst. Auf x86 wird der Stack-Pointer verkleinert, um Platz für die lokalen Variablen der Funktion zu schaffen.
Es können mehrere mögliche Prologe geschrieben werden, was zu einer etwas anderen Stack-Konfiguration führt. Diese Unterschiede sind akzeptabel, solange der Programmierer oder Compiler den Stack innerhalb der Funktion korrekt verwendet.
Als Beispiel ist hier ein typischer Prolog einer x86-Assemblersprache, wie er vom GCC erstellt wurde
push ebp
mov ebp, esp
sub esp, N
Der unmittelbare N- Wert ist die Anzahl der Bytes, die auf dem Stack für die lokale Verwendung reserviert sind.
Das gleiche Ergebnis kann mit der enter
Anweisung erreicht werden:
enter N, 0
Komplexere Prologe können unter Verwendung anderer Werte (anders als 0) für den zweiten Operanden des enter
Befehls erhalten werden. Diese Prologe drücken mehrere Basis-/Rahmenzeiger, um verschachtelte Funktionen zu ermöglichen , wie sie von Sprachen wie Pascal erforderlich sind . Moderne Versionen dieser Sprachen verwenden diese Anweisungen jedoch nicht, da sie in einigen Fällen die Verschachtelungstiefe einschränken.
Epilog
Funktionsepilog kehrt die Aktionen des Funktionsprologs um und gibt die Kontrolle an die aufrufende Funktion zurück. Es führt normalerweise die folgenden Aktionen aus (dieses Verfahren kann sich von Architektur zu Architektur unterscheiden):
- Legen Sie den Stapelzeiger auf den aktuellen Basiszeiger ab, damit im Prolog reservierter Platz für lokale Variablen frei wird.
- Entfernt den Basiszeiger vom Stapel, sodass er auf seinen Wert vor dem Prolog zurückgesetzt wird.
- Kehrt zur aufrufenden Funktion zurück, indem der Programmzähler des vorherigen Frames vom Stack entfernt und zu ihm gesprungen wird.
Der gegebene Epilog wird die Auswirkungen eines der oben genannten Prologe rückgängig machen (entweder des vollständigen oder desjenigen, der verwendet wird enter
). Unter bestimmten Aufrufkonventionen liegt es in der Verantwortung des Angerufenen, die Argumente vom Stapel zu entfernen, daher kann der Epilog auch den Schritt beinhalten, den Stapelzeiger nach unten oder oben zu bewegen.
Diese drei Schritte können beispielsweise in der 32-Bit-x86-Assemblersprache durch die folgenden Anweisungen ausgeführt werden:
mov esp, ebp
pop ebp
ret
Wie der Prolog enthält der x86- Prozessor eine eingebaute Anweisung, die einen Teil des Epilogs ausführt. Der folgende Code entspricht dem obigen Code:
leave
ret
Die leave
Anweisung führt die mov
und pop
Anweisungen aus, wie oben beschrieben.
Eine Funktion kann mehrere Epiloge enthalten. Jeder Funktionsausgangspunkt muss am Ende entweder zu einem gemeinsamen Epilog springen oder einen eigenen Epilog enthalten. Daher verwenden Programmierer oder Compiler oft die Kombination von leave
und ret
um die Funktion an jedem Punkt zu beenden. (Beispielsweise würde ein C- Compiler eine return
Anweisung durch eine leave
/ ret
-Sequenz ersetzen ).
Weiterlesen
- de Boyne Pollard, Jonathan (2010). "Die Gen-on-Funktion Periloge" . Häufig gegebene Antworten .