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