Introduction Pratique Assembleur

publicité
Architecture d’Ordinateurs
Introduction Pratique Assembleur
Introduction
L’objectif de ce document est de donner les détails pratiques pour écrire, compiler et exécuter les premiers
programmes en Assembleur. On va travailler sur la machine sirius où on dispose du compilateur nasm. Pour
se connecter à sirius, démarrer l’ordinateur sous Linux. Dans la fenêtre “Gestionnaire de bureaux GNOME”
il faut choisir Action et après “Connexion distante via XDMCP”. Choisir sirius comme hôte et se connecter.
D’abord, il faut créer un répertoire TP1_NOM_PRENOM où on peut créer le fichier bonjour.nasm dans lequel
on va écrire nos programmes. Je vous conseille d’utiliser l’éditeur Kate car il permet de faire la coloration
syntaxique (si besoin, il faut sélectionner Tools→Highlighting→Assembler→ Intel X86 nasm).
Voici un premier exemple de programme qui affiche la chaı̂ne Bonjour !
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
g l o b a l main
; c e c i e s t un commentaire
extern p r i n t f
SECTION .data
bonjour :
db ”Bonjour ! ” , 1 0 , 0 ; 10 =c a r a c t è r e ASCI Line Feed ( l e s a u t de l i g n e ”\ n ” en C)
; 0 = c a r a c t è r e pour marquer l a f i n de c h aı̂ n e ( pour p r i n t f )
SECTION . t e x t
g l o b a l main
main :
push
ebp
mov
ebp , esp
pushad
pushad
push
call
popad
add
popad
xor
mov
pop
ret
dword b o n j o u r
printf
; on mets l ’ a d r e s s e de l a c h aı̂ n e dans l a p i l e
esp , 4
; pop s t a c k ( d é p i l e r ) une f o i s
eax , eax
esp , ebp
ebp
; return value = 0
Notons que les lignes 1-3, 6-11 et 19-23 ne doivent pas être modifiées dans les programmes que vous
écrivez ensuite. Pour compiler ce programme, on va créer dans le même répertoire un fichier Makefile qui
contient :
all :
[TAB] nasm −f e l f −g b o n j o u r . nasm
[TAB] g c c −ggdb −o b o n j o u r b o n j o u r . o
Dans ce fichier Makefile, [TAB] fait référence à la touche Tabulation. Ouvrez une console (terminal) est
aller dans le répertoire TP1_NOM_PRENOM qui contient ces deux fichiers (Makefile et bonjour.nasm). Tapez
make pour compiler et ./bonjour pour exécuter.
Modifier le fichier bonjour.nasm afin de résoudre les exercices de TP1.
Indications : Pour l’exercice 1 du TP1, on utilise l’instruction mov (pour mettre les valeurs de a et b
dans les registres EAX et EBX), suivie par cmp (cet instruction compare deux registres – EAX et EBX – et mets
le résultat dans le registre flags), suivi par une instruction jle (Jump if Lower or Equal – au cas où le
résultat stocké dans le registre flags indique que la valeur de EAX est inférieure à celle de EBX, le programme
effectue un saut).
Pour avoir des renseignements sur une instruction, vous pourriez consulter le cours, ainsi que des matériaux sur Internet, e.g. une liste d’instructions se trouve à en.wikipedia.org/wiki/X86_instruction_
listings
TP Architecture des ordinateurs, M2 CCI, Université d’Angers – 2009-2010
Daniel Porumbel
Le programme suivant compare deux nombres a et b et affiche leur relation d’ordre.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
g l o b a l main
extern p r i n t f
SECTION .data
a
dd 10
b
dd 9
b o n j o u r : db ”Bonjour ! ” , 1 0 , 0
msgInf : db ”a<b ” , 1 0 , 0
msgSup : db ”a>=b ” , 1 0 , 0
SECTION . t e x t
g l o b a l main
main :
push
mov
pushad
mov
mov
cmp
jl
pushad
push
call
popad
add
jmp
; c e c i e s t un commentaire
; a e s t un e n t i e r s u r 32 b i t s , sa v a l e u r e s t 10
; b e s t un e n t i e r s u r 32 b i t s , sa v a l e u r e s t 9
ebp
ebp , esp
eax , [ a ]
ebx , [ b ]
eax , ebx
inf
dword msgSup
printf
; on mets l ’ a d r e s s e de l a c h aı̂ n e dans l a p i l e
esp , 4
fin
; pop s t a c k ( d é p i l e r ) une f o i s
; on ne v e u t pas c o n t i n u e r à a f f i c h e r
dword msgInf
printf
; on mets l ’ a d r e s s e de l a c h aı̂ n e dans l a p i l e
esp , 4
; pop s t a c k ( d é p i l e r ) une f o i s
eax , eax
esp , ebp
ebp
; v a l e u r de r e t o u r du programme = 0
msgInf
inf :
pushad
push
call
popad
add
fin :
popad
xor
mov
pop
ret
Pour faire tourner ce programme, il est convenable d’écrire ce code dans le fichier bonjour.nasm et de
le compiler avec la commande make. Ensuite, pour résoudre d’autre exercices, il est conseiller de travailler
que avec le fichier bonjour.nasm que vous pouvez le modifier. Informations utiles :
– Observez que ce programme a plusieurs variables dans la section .data, e.g. a, b, msgInf, msgSup.
Les types de donnés qu’on utilise sont : db (data byte), dw (data word) et dd (data double). Un variable
déclarée db est codé sur un octet (ou une série de plusieurs octets comme pour les variables msgIng,
msgSup). Pour stocker les nombres a et b, on utilise des variables à 4 octets (dd) car les registres eax et
ebx ont 4 octets (32 bits). Observez que la valeur d’une variable est lue/écrite en utilisant les crochets.
Un exemple de déclaration de tableau de 100 entiers de valeur 7 est monTableau : times 100 dd 7
– Les registres qu’on va utiliser le plus souvent sont : eax, ebx, ecx, edx (registres génériques) ; ebp,
esp (registres utilisés exclusivement pour traiter la pile d’exécution du programme) ; il faut aussi
connaı̂tre le registre EIP (Instruction Pointer) qui représente l’adresse mémoire de l’instruction courante. La pile est importante quand on écrit des sous-programmes ou des procédures.
TP Architecture des ordinateurs, M2 CCI, Université d’Angers – 2009-2010
Daniel Porumbel
– Les principales instructions utilisés dans le TP d’assembleur sont :
– mov dest,src copie le contenu de src en dest. Par exemple :
mov eax,[a] ; copie la valeur de a dans le registre eax
– jmp étiquette fait un saut à une adresse étiquette, voir lignes 27 et 34 pour la déclaration des
étiquettes de saut
– cmp op1, op2
fait une comparaison entre op1 et op2 (voir ligne 19). Le résultat de cette
comparaison est stocké dans un autre registre (FLAGS) et la prochaine instruction (de saut) est
capable de lire ce résultat.
– jl étiquette fait un saut à l’adresse étiquette si la dernière comparaison à eu comme résultat
op1<op2. Il y a en fait une série d’instruction de ce type : jl(Jump if Lower), jle (Jump if Lower of
Equal), jg (Jump if Greater), etc.
– push et pop instructions pour empiler et dépiler. Par exemple :
1
2
3
4
5
6
7
8
9
mov eax ,
push eax
mov ebx ,
mov ecx ,
push ebx
push ecx
pop edx
pop eax
pop ebx
7 ; l a v a l e u r 7 s e r a dans l e r e g i s t r e eax
; l a v a l e u r de eax ( 7 ) e s t mise au sommets de l a p i l e
9 ;
5 ;
; la p i l e sera : 7 9
; edx s e r a 5 e t l a
; eax s e r a 9 e t l a
; ebx sera 7 e t l a
5
pile : 7 9
pile : 7
p i l e vide
Notons que l’instruction add esp,4 enlève pratiquement la valeur du sommet de la pile, e.g. si on
ajoute add esp, 4 avant pop edx, alors edx sera 9.
– call maProcedure appelle la procédure maProcedure, e.g. voir ligne 24 où on appelle printf
– ret cette instruction termine la procédure courante et renvoie la valeur de eax
– Add, Sub, Mul, Div, Inc, Dec, Shl, Sar ce sont des instructions pour des opérations mathématiques.
Par exemple :
1
2
3
4
5
mov
mov
add
mov
sub
eax ,
ebx ,
eax ,
ecx ,
eax ,
7
5
ebx
10
ecx
;
;
;
;
;
eax=7
e b x=5
eax s e r a 12
eax s e r a 2
D’autres exemples d’instructions arithmétiques sont disponibles à en.wikibooks.org/wiki/X86_
Assembly/Arithmetic.
TP Architecture des ordinateurs, M2 CCI, Université d’Angers – 2009-2010
Daniel Porumbel
Téléchargement