Considerações para escrever código de prólogo/Epilog
Específicos do Microsoft
Antes de escrever seus próprios prólogo e epilog as seqüências de código, é importante entender como o quadro de pilha é apresentado.Também é útil saber como usar o __LOCAL_SIZE símbolo.
Layout de quadro de pilha
Este exemplo mostra o código de prólogo padrão que podem ser exibidos 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
O localbytes variável representa o número de bytes necessários na pilha para variáveis locais e o <registers> variável é um espaço reservado que representa a lista de registros a serem salvos na pilha.Após empurrando os registradores, você pode colocar todos os outros dados apropriados na pilha.Este é o código de epilog correspondente:
pop <registers> ; Restore registers
mov esp, ebp ; Restore stack pointer
pop ebp ; Restore ebp
ret ; Return from function
Sempre a pilha cresce para baixo (de alta para os endereços de memória insuficiente).O ponteiro de base (ebp) aponta para o valor enviado de ebp.A área de locals começa em ebp-4.Para acessar as variáveis locais, calcular um deslocamento de ebp , subtraindo o valor apropriado do ebp.
__LOCAL_SIZE
O compilador fornece um símbolo, __LOCAL_SIZE, para uso no bloco de montador de entre linhas do código de prólogo da função.Este símbolo é usado para alocar espaço para as variáveis locais no quadro de pilha no código de prólogo personalizado.
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 gerado pelo compilador.__LOCAL_SIZE podem ser usados apenas como um operando imediato; ele não pode ser usado em uma expressão.Você não deve alterar ou redefinir o valor deste símbolo.Por exemplo:
mov eax, __LOCAL_SIZE ;Immediate operand--Okay
mov eax, [ebp - __LOCAL_SIZE] ;Error
O exemplo a seguir de uma função nua contendo prólogo personalizado e epilog sequences usa a __LOCAL_SIZE o símbolo da seqüê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
}
}