Udostępnij za pośrednictwem


Zagadnienia dotyczące pisania kodu prologu/epilogu

Specyficzne dla firmy Microsoft

Przed napisaniem własnej sekwencji kodu prologu i epilogu ważnym jest, aby zrozumieć układanie ramek stosu.Warto także dowiedzieć się, jak używać symbolu __LOCAL_SIZE.

Układ ramki stosu

W tym przykładzie pokazano standardowy kod prologu, który może pojawić się w 32 bitowej funkcji:

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

Zmienna localbytes reprezentuje liczbę bajtów potrzebnych na stosie dla zmiennych lokalnych a zmienna <registers> jest symbolem zastępczym reprezentującym listę rejestrów, które mają być zapisane na stosie.Po umieszczeniu rejestrów na stosie, można tam umieścić inne odpowiednie dane.Poniżej przedstawiono odpowiadający kod epilogu:

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

Stos zawsze powiększa się w dół (od najwyższego do najniższego adresu pamięci).Podstawowy wskaźnik (ebp) wskazuje na umieszczoną wartość ebp.Obszar lokalny rozpoczyna się od ebp-4.Aby uzyskać dostęp do zmiennych lokalnych, należy obliczyć przesunięcie z ebp przez odjęcie odpowiedniej wartości od ebp.

__LOCAL_SIZE

Kompilator dostarcza symbolu __LOCAL_SIZE, do użytku w bloku asemblera wbudowanego w kodzie prologu funkcji.Ten symbol jest używany do alokowania miejsca dla zmiennych lokalnych na ramkach stosu w niestandardowym kodzie prologu.

Kompilator określa wartość __LOCAL_SIZE.Jej wartością jest całkowita liczba bajtów wszystkich zmiennych lokalnych zdefiniowanych przez użytkownika i zmiennych tymczasowych wygenerowanych przez kompilator.__LOCAL_SIZE może być używana tylko jako bezpośredni argument; Nie może być użyta w wyrażeniu.Nie wolno zmieniać lub ponownie definiować wartości tego symbolu.Na przykład:

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

Poniższy przykład nagiej funkcji zawiera niestandardowe sekwencje prologu i epilogu, i używa symbolu __LOCAL_SIZE w sekwencji prologu:

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

Zobacz też

Informacje

Wywołania funkcji Naked