Tp1 : L'assemblage,l'édition des liens et la compilation



L'objectif

Il est de constater qu'un programme écrit en assembleur fait la même chose qu'un programme écrit en C. Nous allons aussi voir les notions de point d'entrée d'un programme et les différentes phases de compilation.

Le temps imparti

1h30

Le sujet

Ce tp comporte trois programmes, hello1.s, hello2.s et hello3.c qui affichent à l'écran le message hello world !. Vous allez devoir constater les principes de l'assemblage, l'édition des liens et de la compilation


A faire

Saisir le programme suivant à l'aide d'un éditeur de texte (emacs, vi, ...)
On ne saisit pas les numéros de ligne !!!

hello1.s
  1. .text
  2. message :
  3. .ascii "hello world ! \0"
  4. .align 4
  5. .global main
  6. main :
  7. pushl %ebp
  8. movl %esp,%ebp
  9. pushl $message
  10. call puts
  11. addl $4,%esp
  12. movl %ebp,%esp
  13. popl %ebp
  14. ret

L'assembler en tapant la commande suivante :

$as hello1.s -o hello1.o

Lancer la commande ls et constater la présence du fichier hello1.o, qui est un fichier binaire compréhensible par le microprocesseur.
Faire l'édition des liens en tapant la commande suivante :

$gcc hello1.o -o hello1

Lancer la commande ls et constater la présence du fichier hello1.
Lancer le programme hello1, il doit vous afficher le message : "hello world !".

Il était aussi possible de réaliser l'assemblage en tapant la commande :

$gcc -c hello1.s -o hello1.o


Saisir le programme suivant à l'aide d'un éditeur de texte :

Hello2.s
  1. .text
  2. message :
  3. .ascii "hello world ! \12\0"
  4. .align 4
  5. .global _pointdentree
  6. _pointdentree:
  7. movl $4,%eax
  8. movl $1,%ebx
  9. movl $message,%ecx
  10. movl $15,%edx
  11. int $0x80
  12. movl $1,%eax
  13. movl $0,%ebx
  14. int $0x80

L'assembler en tapant la commande suivante :

$as hello2.s -o hello2.o

Lancer la commande ls et constater la présence du fichier hello2.o.
Faire l'édition des liens en tapant la commande suivante :

$ld -o hello2 -e _pointdentree hello2.o

Lancer la commande ls et constater la présence du fichier hello2.
Lancer le programme hello2, il doit vous afficher le message : "hello world !".
Comparer la taille des deux fichiers hello1 et hello2. Nous verrons un peu plus loin le pourquoi de cette différence de taille.


Saisir le programme suivant à l'aide d'un éditeur de texte :

Hello3.c
  1. int main( )
  2. {
  3. printf("Hello world !\n");
  4. }

Le compiler en tapant la commande suivante :

$gcc hello3.c -o hello3

Lancer la commande ls et constater la présence du fichier hello3.
Lancer le programme hello3, il doit vous afficher le message : "hello world !".
Traduire le fichier C hello3.c en langage d'assemblage en tapant la commande suivante :

$gcc -S hello3.c -o hello3.s

Comparer les deux fichiers hello1.s et hello3.s en les éditant.


Copier le fichier hello1.s dans le fichier hello4.s.
Remplacer dans le fichier hello4.s puts par printf et \0 par \12\0.
Réaliser l'exécutable, Lancer et conclure

Dans hello4.s, enlever \12, refaire l'exécutable, le relancer et constater.


Nous allons voir maintenant qu'il est possible d'obtenir un exécutable des deux programmes hello1 et hello2 en utilisant ld pour le premier et gcc pour le second.

Pour le fichier : hello1.s :

Faire l'édition des liens de hello1 en tapant la commande suivante :

$ld -o hello1 hello1.o

Vous devez obtenir le message suivant :
  ld: warning: cannot find entry symbol _start; defaulting to 08048074
  hello1.O(.text+0x19): undefined reference to `puts'

Explication : il y a 2 problèmes :

Pour le fichier : hello2s :

Compiler le programme hello2.s en tapant la commande suivante :

$gcc hello2.s -o hello2

Vous devez obtenir le message suivant :
  /usr/lib/crt1.o(.text+0x18): undefined reference to `main'

Explication : le problème, vient de ce que gcc cherche le point d'entrée main et ne le trouve. Par contre si vous lancez la commande suivante :

$gcc -S hello2.s -o hello2

Cela revient à faire en sorte que gcc ne s'occupe pas du point d'entrée lors de l'assemblage, puisqu'il ne fait pas l'édition des liens.

Modifier hello2.s en remplaçant _pointdentree par main et relancer gcc. A partir de là tout doit bien se passer.

Conclure sur ce premier TP.


Retour à la liste des TP