Environnement 32 bits
Nous avons choisi de travailler sur les microprocesseurs Intel x86, c’est-`
a-dire compatibles avec le jeu
d’instructions de l’Intel 8086. Les versions les plus r´
ecentes de cette famille (depuis 2003 quand mˆ
eme !)
sont des microprocesseurs 64 bits (Athlon 64, Opteron, Pentium 4 Prescott, Intel Core 2, etc.).
Ces processeurs 64 bits peuvent fonctionner en mode compatibilit´
e 32 bits avec le jeu d’instructions
restreint de l’Intel 8086.
Sur ces machines, on indique au compilateur GCC de g´
en´
erer du code 32 bits en lui sp ´
ecifiant l’option
-m32.
Premi`
ere r´
ealisation pratique
Dans un premier temps, fournissez un moyen d’afficher la valeur des registres %esp et %ebp de la fonction
courante.
— Observez ces valeurs sur un programme simple compos ´
e d’appels imbriqu ´
es puis successifs `
a
des fonctions.
— Comparez ces valeurs avec les adresses des premi `
ere et derni `
ere variables automatiques lo-
cales d ´
eclar ´
ees dans ces fonctions.
— Comparez ces valeurs avec les adresses des premier et dernier param`
etres de ces fonctions.
— Expliquez.
Implantez votre biblioth `
eque de retour dans la pile d’ex´
ecution et testez son comportement sur une va-
riante du programme de l’exercice 3.
Observez l’ex´
ecution de ce programme sous le d ´
evermineur ; en particulier positionnez un point d’arr ˆ
et
dans throw() et continuez l’ex´
ecution en pas `
a pas une fois ce point d’arr ˆ
et atteint.
Contexte d’ex´ecution
Pour s’ex´ecuter, les proc´edures d’un programme en langage C sont compil´ees en code ma-
chine. Ce code machine exploite lors de son ex´ecution des registres et une pile d’ex´ecution.
Dans le cas d’un programme compil´e pour les microprocesseurs Intel x86, le sommet de la pile
d’ex´ecution est point´e par le registre 32 bits %esp (
stack pointer
). Par ailleurs le microprocesseur
Intel d´efinit un registre d´esignant la base de la pile, le registre %ebp (
base pointer
).
Ces deux registres d´efinissent deux adresses, `a l’int´erieur de la zone r´eserv´ee pour la pile
d’ex´ecution, l’espace qui les s´epare est la fenˆetre associ´ee `a l’ex´ecution d’une fonction (
frame
) :
%esp pointe le sommet de cette zone et %ebp la base.
Grossi`erement, lorsque une proc´edure est appel´ee, les registres du microprocesseur (except´e
%esp) sont sauv´es au sommet de la pile, puis les arguments sont empil´es et enfin le pointeur de
programme, avant qu’il branche au code de la fonction appel´ee. Notez encore que la pile Intel
est organis´ee selon un ordre d’adresse d´ecroissant (empiler un mot de 32 bits en sommet de pile
d´ecr´emente de 4 l’adresse point´ee par %esp).
Sauvegarder les valeurs des deux registres %esp et %ebp suffit `a m´emoriser un contexte dans
la pile d’ex´ecution.
Restaurer les valeurs de ces registres permet de se retrouver dans le contexte sauvegard´e.
Une fois ces registres restaur´es au sein d’une fonction, les acc`es aux variables automatiques (les
variables locales allou´ees dans la pile d’ex´ecution) ne sont plus possibles, ces acc`es ´etant r´ealis´es
par indirection `a partir de la valeur des registres.
L’acc`es aux registres du processeur peut se faire par l’inclusion de code assembleur au sein
du code C ; voir l’encart page pr´ec´edente.
Implantation d’une biblioth`eque de retour dans la pile d’ex´ecution
On d´efinit un jeu de primitives pour retourner `a un contexte pr´ealablement m´emoris´e dans
une valeur de type struct ctx s.
4