Überlegungen für das Schreiben des Prolog-/Epilogcodes
Microsoft-spezifisch
Bevor Sie Eigene Prolog- und Epilog-Codesequenzen schreiben, ist es wichtig zu verstehen, wie der Stapelrahmen angeordnet ist. Es ist auch hilfreich, um zu wissen, wie das __LOCAL_SIZE
Symbol verwendet wird.
Stapelrahmenlayout
In diesem Beispiel wird der Standardprologcode veranschaulicht, der in einer 32-Bit-Funktion enthalten sein kann:
push ebp ; Save ebp
mov ebp, esp ; Set stack frame pointer
sub esp, localbytes ; Allocate space for locals
push <registers> ; Save registers
Die localbytes
-Variable gibt die Anzahl von Bytes an, die auf dem Stapel für lokale Variablen erforderlich sind. Die <registers>
-Variable ist ein Platzhalter, der die Liste der Register darstellt, die auf dem Stapel gespeichert werden sollen. Nach dem Verschieben der Register können Sie alle weiteren entsprechenden Daten auf dem Stapel platzieren. Im Folgenden wird der entsprechende Epilogcode dargestellt:
pop <registers> ; Restore registers
mov esp, ebp ; Restore stack pointer
pop ebp ; Restore ebp
ret ; Return from function
Der Stapel wächst immer nach unten (von hohen zu niedrigen Speicheradressen). Der Basiszeiger (ebp
) zeigt auf den abgelegten ebp
-Wert. Der Gültigkeitsbereich der lokalen Variablen beginnt bei ebp-4
. Um auf lokale Variablen zuzugreifen, berechnen Sie einen Offset von ebp
, indem Sie den entsprechenden Wert von ebp
subtrahieren.
__LOCAL_SIZE
Der Compiler stellt ein Symbol __LOCAL_SIZE
für die Verwendung im Inlineassemblerblock des Funktionsprologcodes bereit. Mit diesem Symbol wird Speicherplatz für lokale Variablen im Stapelrahmen im benutzerdefinierten Prologcode zugeordnet.
Der Compiler bestimmt den Wert von __LOCAL_SIZE
. Sein Wert ist die Gesamtzahl von Bytes aller benutzerdefinierten lokalen Variablen und der vom Compiler generierten temporären Variablen. __LOCAL_SIZE
kann nur als sofortiger Operand verwendet werden; sie kann nicht in einem Ausdruck verwendet werden. Sie dürfen den Wert dieses Symbols nicht ändern oder neu definieren. Beispiel:
mov eax, __LOCAL_SIZE ;Immediate operand--Okay
mov eax, [ebp - __LOCAL_SIZE] ;Error
Im folgenden Beispiel einer nackten Funktion, die benutzerdefinierte Prolog- und Epilogsequenzen enthält, wird das __LOCAL_SIZE
Symbol in der Prologsequenz verwendet:
// the__local_size_symbol.cpp
// processor: x86
__declspec ( naked ) int main() {
int i;
int j;
__asm { /* prolog */
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
}
/* Function body */
__asm { /* epilog */
mov esp, ebp
pop ebp
ret
}
}
Ende Microsoft-spezifisch
Siehe auch
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für