Freigeben über


Ü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
      }
}

Siehe auch

Referenz

Nackte Funktionsaufrufe