Considérations sur l'écriture de code de prologue/épilogue
Section spécifique à Microsoft
Avant d’écrire vos propres séquences de code prolog et épilogue, il est important de comprendre comment le frame de pile est disposé. Il est également utile de savoir comment utiliser le __LOCAL_SIZE
symbole.
Disposition du cadre de pile
Cet exemple montre le code de prologue standard qui peut apparaître dans une fonction 32 bits :
push ebp ; Save ebp
mov ebp, esp ; Set stack frame pointer
sub esp, localbytes ; Allocate space for locals
push <registers> ; Save registers
La variable localbytes
représente le nombre d'octets nécessaires sur la pile pour les variables locales. La variable <registers>
est un espace réservé qui représente la liste de registres à enregistrer sur la pile. Après avoir effectué un push des registres, vous pouvez placer toutes les autres données pertinentes sur la pile. Voici le code d'épilogue correspondant :
pop <registers> ; Restore registers
mov esp, ebp ; Restore stack pointer
pop ebp ; Restore ebp
ret ; Return from function
La pile se réduit toujours (des adresses de mémoire supérieures aux adresses de mémoire inférieures). Le pointeur de base (ebp
) pointe vers la valeur de ebp
qui fait l'objet d'un push. La zone Variables locales commence à ebp-4
. Pour accéder aux variables locales, calculez un décalage à partir de ebp
en soustrayant la valeur appropriée de ebp
.
__LOCAL_SIZE
Le compilateur fournit un symbole, __LOCAL_SIZE
à utiliser dans le bloc assembleur inline du code prolog de fonction. Ce symbole est utilisé pour allouer de l'espace pour les variables locales sur le frame de pile dans le code de prologue personnalisé.
Le compilateur détermine la valeur de __LOCAL_SIZE
. Sa valeur représente le nombre total d'octets de toutes les variables locales définies par l'utilisateur et des variables temporaires générées par le compilateur. __LOCAL_SIZE
ne peut être utilisé qu’en tant qu’opérande immédiat ; elle ne peut pas être utilisée dans une expression. Vous ne devez pas modifier ou redéfinir la valeur de ce symbole. Par exemple :
mov eax, __LOCAL_SIZE ;Immediate operand--Okay
mov eax, [ebp - __LOCAL_SIZE] ;Error
L’exemple suivant d’une fonction nue contenant des séquences de prolog et d’épilogue personnalisées utilise le __LOCAL_SIZE
symbole dans la séquence de prologue :
// 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
}
}
FIN de la section spécifique à Microsoft
Voir aussi
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour