Compartilhar via


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

Seção específica 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 é disposto. Também é útil saber como usar a constante predefinida __LOCAL_SIZE.

Layout do quadro CStack

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 variáveis locais começa em ebp-2. Para acessar variáveis locais, calcule um deslocamento de ebp subtraindo o valor apropriado de ebp.

A constante __LOCAL_SIZE

O compilador fornece uma constante, __LOCAL_SIZE, para o uso no bloco embutido do assembler do código do prólogo da função. Essa constante é usada 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. O 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 usada apenas como um operando imediato; não pode ser usada em uma expressão. Você não deve alterar ou redefinir o valor dessa constante. 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 __LOCAL_SIZE na sequência de prólogo:

__declspec ( naked ) func()
{
   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
      }
}

Fim da seção específica da Microsoft

Confira também

Funções naked