Share via


Ü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_SIZEfü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

Naked-Funktionsaufrufe