Überlegungen zum Schreiben von Prolog-/Epilog-Codes
Microsoft-spezifisch
Vor dem Ausführen Einleitungs- und Epilogcode sequenzen besitzen schreibt, ist es wichtig zu verstehen, wie der Stapelrahmen festgelegt ist.Es ist auch hilfreich, können das __LOCAL_SIZE Symbol verwenden.
Stapelrahmen-Lay-out
In diesem Beispiel wird der Standardwert einleitungs Code veranschaulicht, der in einer 32-Bit-Funktion wird:
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 stellt die Anzahl von Bytes dar, die auf dem Stapel für lokale Variablen erforderlich sind, und die <registers>-Variable ist ein Platzhalter, der die Liste der auf dem Stapel darstellt, Register gespeichert werden soll.Nach dem Drucken der Register, können Sie alle weiteren entsprechenden Daten auf dem Stapel platzieren.Im Folgenden wird der entsprechende Epilogcode:
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 (vom Hoch zu niedrigen Speicheradressen).Der niedrige Zeiger (ebp) zeigt auf den gedrückten Wert von ebp.Der Gültigkeitsbereich der lokalen Variablen beginnt bei ebp-4.Um lokale Variablen zuzugreifen, leiten Sie einen Offset von ebp indem Sie den entsprechenden Wert von ebpsubtrahiert wird.
__LOCAL_SIZE
Der Compiler stellt ein Symbol, __LOCAL_SIZEfür die Verwendung im Code einleitungs Funktionen des Inlineassembler Datenbindungsausdrücken bereit.Dieses Symbol wird verwendet, um Platz für lokale Variablen auf dem Stapelrahmen im benutzerdefinierten vorläufige Code zuzuordnen.
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 unmittelbarer Operand verwendet werden. er kann nicht in einem Ausdruck verwendet werden.Sie dürfen den Wert dieses Symbols ändern oder neu definieren.Beispiele:
mov eax, __LOCAL_SIZE ;Immediate operand--Okay
mov eax, [ebp - __LOCAL_SIZE] ;Error
Im folgenden Beispiel einer nackten benutzerdefinierte Funktion, die Einleitungs- sequenzen und Epilog verwendet, enthält das __LOCAL_SIZE Symbol in der vorläufige: sequence
// 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
}
}