TP5 – La famille Intel 80x86 et NASM (2 séances)

publicité
Architecture des ordinateurs
TP5 – La famille Intel 80x86 et NASM (2 séances)
Ce TP utilise le processeur Intel de votre ordinateur. On utilise la commande nasm pour assembler
les fichiers assembleurs et la commande ald pour le débogage.
Une documentation sur nasm est disponible à http://deptinfo.unice.fr/~fmallet/archi/nasmdoc.pdf,
cette documentation contient également la liste des instructions Intel que nous pouvons utiliser ainsi
qu'une courte description de leur fonctionnement et des modes d'adressage autorisés. La
commande nasm est directement accessible sur vos machines.
La commande ald quant à elle n'est pas accessible directement, vous devez la copier sur votre
compte depuis ~fmallet/bin/ald. Modifier éventuellement votre variable PATH pour y accéder plus
facilement. La commande ald lance un environnement textuel interactif qui permet de déboguer des
fichiers exécutables. Sous cet environnement taper help pour avoir la liste de toutes les commandes
disponibles.
Ce TP permet essentiellement la prise en main des outils ald et nasm.
Exercice 5.1 – Mon premier programme
On veut écrire un programme simple qui effectue l'opération arithmétique 8+5+3*2.
1. Dans une première version, on n'utilisera que les modes d'adressage par registre et immédiat (pas
de mode d'adressage direct). Consulter la documentation (nasm) pour les instructions add, mul et
mov afin de réaliser ce programme. On considère que 3, 2, 5 et 8 sont des octets (8 bits) non
signés.
2. Taper votre programme dans le fichier premier.asm sans oublier de déclarer la section .text et de
rendre global le label _start. Compiler votre programme par : nasm -f elf premier.asm.
Faire l'édition de lien par : ld -o premier premier.o. Vérifier que le fichier exécutable
premier a bien été créé.
3. Exécuter le programme premier, que se passe-t-il ? Expliquer.
4. Charger le programme premier avec le débogueur ald : ald premier. Utiliser la commande
file pour déterminer l'adresse de la première instruction du programme. On pourra pour cela
utiliser file secinfo pour déterminer la taille et l'adresse de début des sections. Mais rien ne
garantie que le programme commence au début de la section .text. On peut alors utiliser la
commande file header pour déterminer le point d'entrée effectif (entry point).
5. Utiliser la commande examine (exam comme raccourci) pour examiner sous forme
hexadécimale la section .text de la mémoire. Cette forme est bien entendue très peu lisible. On
pourra l'utiliser pour examiner les sections de données, on utilisera en revanche la commande
disassemble (disass comme raccourci) pour examiner les sections de programme.
Une façon plus agréable de dé-assembler une section donnée est : disass -section .text.
6. Constater la taille très variable des instructions.
7. Utiliser la commande register pour voir l'état des registres (tous ou 1 en particulier) ou modifier
leur valeur. Quel est le registre qui indique l’adresse de la prochaine instruction à exécuter ?
Comment faire pour recommencer un programme au début ?
8. Utiliser la commande step pour exécuter votre programme pas à pas et vérifier qu'il réalise le
comportement souhaité. Où est la fin du programme ?
9. Établir un point d’arrêt (commande break) après la dernière instruction valide de votre
programme, ré-exécuter votre programme avec la commande continue. Ce serait bien plus facile
si on avait des labels ? Ajoutez-en un, recompilez !
Frédéric Mallet
Licence Informatique L3
2006/2007
Architecture des ordinateurs
Exercice 5.2 – Modes d'adressage direct et section de données.
On veut maintenant exécuter le même programme avec des valeurs différentes.
1. Essayer d'utiliser la commande enter pour modifier directement dans le programme une des
valeurs (ex., on effectuera 8+3+5x2 au lieu de 8+5+3x2).
2. Proposer une solution, en réalisant un autre programme assembleur qui utilise une section de
donnée et les modes d'adressage direct. Comparer la taille des instructions utilisées avec la
solution précédente. On mémorisera le résultat dans la mémoire (section de données non
initialisées .bss). On utilisera la commande file secinfo pour déterminer l'adresse des zones
de données et vérifier que le programme fait bien ce qu'il est supposé faire.
3. On pourra constater que ça n'a pas l'air de fonctionner correctement, désassembler votre
programme pour identifier le bug de ald et constater que le résultat est en réalité correct.
4. Ré-exécuter plusieurs fois le même programme avec des valeurs différentes sans sortir de
l'environnement ald (commande enter). On essaiera en particulier d'exécuter l'opération
8 + 5 + 3 x -2. Que se passe-t-il?
5. Proposer une solution qui utilise l'instruction imul.
6. Pour mettre en évidence l'importance de faire la différence entre mul et imul on réalisera un
programme qui effectue l'opération (3x-2)/2 en utilisant l'instruction div puis l'instruction idiv.
Exercice 5.3 – Calcul du maximum dans un tableau
On veut maintenant réaliser un programme qui calcule la valeur maximum dans un tableau
d'octets.
1. Écrire un programme assembleur qui réalise ce comportement, on utilisera les instructions loop,
cmp et js. Tester votre programme avec le tableau 0x43, 0x56, 0x5, 0x60, 0x80, 0x12, 0x9.
2. Utiliser la directive de compilation $ pour calculer la taille du tableau sans effort.
3. Tester votre programme avec le tableau 0x43, 0x56, 0x5, 0x60, 0x-80, 0x12, 0x9. Quel est le
résultat obtenu ?
4. Corriger votre programme pour qu'il accepte des nombres négatifs. Quels sont les avantages et
inconvénients de faire ça ?
Exercice 5.4 – L'unité nombres réels (FPU)
On veut réaliser un programme qui utilise le FPU pour calculer le cosinus et le sinus de PI et PI/2.
Ne pas oublier d’initialiser le FPU avec l’instruction FINIT avant toute opération.
1. Réaliser un premier programme qui réalise le calcul sur PI, en utilisant les instructions FLDPI,
FSIN, FCOS et FSTP pour faire le calcul et mémoriser le résultat dans la mémoire. Attention à
manipuler des données de la bonne taille. Commenter sur la précision obtenue pour sinus de PI.
2. Modifier ce programme pour réaliser le calcul sur PI/2. Utiliser la commande examine pour
vérifier que le codage de 2 est correct. On utilisera successivement FDIV et FIDIV.
3. Améliorer votre programme en utilisant la commande FSINCOS.
4. On veut maintenant comparer le gain obtenu. Pour cela il faut répéter les opérations plusieurs
fois (plus de 16 millions de fois sur mon ordinateur) pour obtenir une différence significative. On
terminera le programme par :
MOV EAX,1
MOV EBX,0
INT 0x80
pour le rendre exécutable sans l'utilisation de ald (on expliquera ce bout de code au prochain
TP).
5.
Utiliser la commande unix time pour comparer les performances des 2 solutions.
Frédéric Mallet
Licence Informatique L3
2006/2007
Téléchargement