Compartilhar via


Considerações para escrever código de prólogo/epílogo

Específico da Microsoft

Antes de escrever suas próprias sequências de código de prólogo e epílogo, é importante entender como o registro de ativação é apresentado. Ele também é útil para saber como usar o símbolo __LOCAL_SIZE.

Layout do registro de ativação

Este exemplo mostra o código padrão do prólogo que pode aparecer em uma função de 32 bits:

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

A variável localbytes representa o número de bytes necessários na pilha para as variáveis locais. A variável <registers> é um espaço reservado que representa a lista de registros a serem salvos na pilha. Depois de enviar os registros, você pode colocar todos os outros dados apropriados na pilha. O seguinte exemplo é o código do epílogo correspondente:

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

A pilha sempre vai para baixo (dos endereços de memória mais altos para os mais baixos). O ponteiro de base (ebp) aponta para o valor enviados por push de ebp. A área de locais começa em ebp-4. Para acessar variáveis locais, calcule um deslocamento de ebp subtraindo o valor apropriado de ebp.

__LOCAL_SIZE

O compilador fornece um símbolo, __LOCAL_SIZE, para o uso no bloco embutido do assembler do código do prólogo da função. Esse símbolo é usado para alocar espaço para as variáveis locais no quadro da pilha no código personalizado de prólogo.

O compilador determina o valor de __LOCAL_SIZE. Seu valor é o número total de bytes de todas as variáveis locais definidas pelo usuário e variáveis temporárias geradas pelo compilador. __LOCAL_SIZE pode ser usado apenas como um operando imediato; não pode ser usado em uma expressão. Você não deve alterar ou redefinir o valor desse símbolo. Por exemplo:

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

O exemplo a seguir mostra uma função naked que contém sequências de prólogo e epílogo personalizadas e usa o símbolo __LOCAL_SIZE na sequência de prólogo:

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

Consulte também

Referência

Chamadas de função naked