Sdílet prostřednictvím


Důležité informace k zápisu kódu prologu/epilogu

Specifické pro Microsoft

Před psaním vlastních sekvencí kódu prologu a epilogu je zapotřebí porozumět rozložení rámce zásobníku.Také je užitečné vědět, jak používat konstantu __LOCAL_SIZE.

Rozložení rámce zásobníku

Tento příklad ukazuje standardní kód prologu, který se může vyskytnout v 32bitové funkci:

push        ebp                ; Save ebp
mov         ebp, esp           ; Set stack frame pointer
sub         esp, localbytes    ; Allocate space for locals
push        <registers>        ; Save registers

Proměnná localbytes představuje počet bajtů zásobníku potřebných pro místní proměnné a proměnná <registers> je zástupný symbol představující seznam registrů, které mají být uloženy do zásobníku.Po vložení registrů lze do zásobníku uložit libovolná jiná vhodná data.Následující výpis ukazuje odpovídající kód epilogu:

pop         <registers>   ; Restore registers
mov         esp, ebp      ; Restore stack pointer
pop         ebp           ; Restore ebp
ret                       ; Return from function

Zásobník roste vždy směrem dolů (od vysokých po nízké adresy paměti).Základní ukazatel (ebp) ukazuje na vloženou hodnotu proměnné ebp.Lokální oblast začíná na ebp-4.Chcete-li přistoupit k místním proměnným, vypočítejte posun vůči adrese ebp odečtením příslušné hodnoty od adresy ebp.

__LOCAL_SIZE

Kompilátor poskytuje konstantu __LOCAL_SIZE, kterou lze použít ve vloženém bloku assembleru daného kódu prologu funkce.Tato konstanta se používá k přidělení místa pro místní proměnné v rámci zásobníku ve vlastním kódu prologu.

Hodnotu konstanty __LOCAL_SIZE určuje kompilátor.Hodnotou je celkový počet bajtů všech uživatelem definovaných místních a kompilátorem generovaných dočasných proměnných.Konstantu __LOCAL_SIZE lze použít pouze jako přímý operand. Nelze ji použít ve výrazu.Hodnota této konstanty nesmí být v kódu měněna nebo předefinována.Příklad:

mov        eax, __LOCAL_SIZE           ;Immediate operand--Okay
mov        eax, [ebp - __LOCAL_SIZE]   ;Error

Následující příklad neviditelné funkce obsahující vlastní sekvence prologu a epilogu používá v sekvenci prologu konstantu __LOCAL_SIZE:

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

Viz také

Referenční dokumentace

Volání holé funkce