Vous êtes sur la page 1sur 30

Introduction l'Assembleur GNU

Sous un systme GNU/Linux sur Intel 80386


Par Issam Abdallah
Date de publication : 18 fvrier 2013
Dernire mise jour : 4 juillet 2014

Ce tutoriel va vous donner la description minimale pour coder en assembleur GNU sous un
systme GNU/Linux en utilisant le jeu d'instructions Intel 80386.

Introduction l'Assembleur GNU par Issam Abdallah

I - Introduction..............................................................................................................................................................4
II - Dfinitions prliminaires......................................................................................................................................... 4
II-A - Les systmes de numration........................................................................................................................4
II-B - Le code ASCII...............................................................................................................................................6
II-C - Le code BCD................................................................................................................................................ 7
III - L'assemblage et l'dition de liens sous Linux...................................................................................................... 8
IV - Syntaxe de l'assembleur...................................................................................................................................... 9
IV-A - Les sections.................................................................................................................................................9
IV-B - Les commentaires..................................................................................................................................... 10
IV-C - Les dclarations........................................................................................................................................ 10
IV-D - Les symboles.............................................................................................................................................10
Les symboles locaux.......................................................................................................................................11
IV-D-1 - Le symbole . ............................................................................................................................... 11
IV-E - Les constantes...........................................................................................................................................11
Les nombres entiers....................................................................................................................................... 11
Les caractres.................................................................................................................................................12
Les chanes de caractres............................................................................................................................. 12
IV-F - Les expressions......................................................................................................................................... 12
Prfixes............................................................................................................................................................12
Infixes.............................................................................................................................................................. 13
IV-G - Syntaxe des instructions 80386 (IA-32)....................................................................................................13
Les oprandes.................................................................................................................................................13
L'ordre des oprandes.................................................................................................................................... 13
Les instructions LJMP/LCALL.........................................................................................................................13
IV-H - Les directives.............................................................................................................................................14
.ascii string_1, string_2 ......................................................................................................................... 14
.asciz string_1, string_2 .........................................................................................................................14
.byte expression_1, expression_2 ..............................................................................................................14
.word expression_1, expression_2 .............................................................................................................14
.quad expression_1, expression_2 ............................................................................................................ 15
.int expression_1, expression_2 .................................................................................................................15
.long expression_1, expression_2 ..............................................................................................................15
.fill repeat, size, value..................................................................................................................................... 15
.org new-lc, fill................................................................................................................................................. 15
.lcomm symbol, length.................................................................................................................................... 15
.global symbol................................................................................................................................................. 16
.set symbol, expression et .equ symbol, expression...................................................................................... 16
V - Exemples de codes assembleur......................................................................................................................... 16
V-A - Exemple 1 : tri bulles d'une liste d'entiers...............................................................................................16
Dclaration des variables................................................................................................................................16
tape 1 : entrer la liste d'entiers au clavier....................................................................................................16
tape 2 : convertir les caractres du buffer................................................................................................... 17
tape 3 : trier la liste...................................................................................................................................... 19
tape 4 : afficher la liste trie.........................................................................................................................19
V-B - Exemple 2 : les sous-programmes en assembleur.................................................................................... 20
Le stack frame................................................................................................................................................ 20
Les tapes suivre........................................................................................................................................ 21
V-C - Exemple 3 : interfacer du code assembleur et du langage C....................................................................22
Le Makefile...................................................................................................................................................... 22
V-D - Exemple 4 : un programme d'amorage.................................................................................................... 23
Le mode rel................................................................................................................................................... 23
L'architecture interne du processeur en mode rel........................................................................................23
L'adressage de la mmoire en mode rel......................................................................................................24
Le BIOS...........................................................................................................................................................24
L'IVT : Interrupt Vector Table.......................................................................................................................... 25
Un programme d'amorage minimal...............................................................................................................26
Assemblage et dition de liens.......................................................................................................................27
VI - Rfrences..........................................................................................................................................................30
-2-

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

VII - Remerciements.................................................................................................................................................. 30

-3-

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

I - Introduction
L'assembleur est un langage dit bas niveau, c'est--dire qu'il est trs proche du langage machine.
Autrement dit, pour programmer en assembleur vous devez :

apprendre une architecture : Intel par exemple ;


avoir quelques connaissances basiques sur les systmes d'exploitation : Linux par exemple ;
matriser un assembleur : l'assembleur GNU par exemple.

Apprendre une architecture, c'est comprendre le fonctionnement d'un processeur : les registres, l'adressage et
l'organisation de la mmoire, les interruptions et tout ce que vous avez appris dans le cours d'architecture des
ordinateurs. Vous avez, sans doute, une ide claire et suffisante sur l'architecture Intel (IA ou x86) pour aborder ce
tutoriel. D'autre part, apprendre un assembleur c'est apprendre une syntaxe pour programmer. C'est l'objectif de ce
tutoriel !
Le langage assembleur, ou simplement l'assembleur, est une reprsentation symbolique du langage machine
(donnes binaires et instructions du processeur). Il existe deux syntaxes d'assembleurs :

l'assembleur Intel : l'assembleur principal utilisant cette syntaxe est NASM ;


l'assembleur AT&T : l'assembleur principal est l'assembleur GNU ou simplement as.

Ce tutoriel va vous donner la description minimale pour coder en assembleur GNU sous un systme GNU/Linux en
utilisant le jeu d'instructions Intel 80386.
Les codes sources des exemples cits dans ce tutoriel sont tlchargeables sur

cette page.

II - Dfinitions prliminaires
II-A - Les systmes de numration
Pour tre traite par un circuit numrique (un processeur, une mmoire RAM), une information doit tre convertie
en un format adaptable. Pour cela, elle doit tre reprsente dans un systme de numration caractris par une
base b (b > 1 est un entier). Les systmes de numration les plus utiliss sont : le dcimal (b = 10), le binaire (b = 2),
l'octal (b = 8), l'hexadcimal (b = 16).
Tableau 1 : Les systmes de numration

-4-

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Dcimal

0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111

Binaire

0
1
2
3
4
5
6
7
10
11
12
13
14
15
16
17

Octal

0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F

Hexadcimal

On crit un nombre N = an an1 a1 a0 , a1 a2 am dans un systme de numration de base b selon


l'expression suivante :
i
n
n1
1
0
1
2
m
N = min (ai.b ) = an.b + an1.b
a1.b + a0.b , a1.b + a2.b am.b
Avec i le poids (position) du chiffre (digit) ai dans le nombre N.
Exemples :

3
2
1
0
b = 10 et N = 2193 : 219310 = 2.10 + 1.10 + 9.10 + 3.10 = 2000 + 100 + 90 + 3
= 2193 ;
3
2
1
0
b = 2 et N = 1011 : 10112 = 1.2 + 0.2 + 1.2 + 1.2 = 8 + 0 + 2 + 1
= 11 ;
3
2
1
0
b = 16 et N = F3C9 : F3C916 = 15.16 +3.16 +12.16 +9.16 = 61440+768+192+9
= 62409 ;
1
0
1
2
b = 2 et N = 10,11 : 10,112 = 1.2 + 0.2 + 1.2 + 1.2 = 2 + 0 + 0,5 + 0,25
= 2,75.

En fait, nous avons converti les quatre nombres N reprsents dans les systmes de numration de bases b au
format dcimal.
Il est clair que la base b d'un systme de numration est gale au nombre de chiffres (digits) qui peuvent tre utiliss
pour reprsenter un nombre. Ainsi, le systme binaire utilise deux digits {0, 1}, le systme dcimal utilise dix digits
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} et ainsi de suite.
D'autre part, pour adapter un systme de numration un circuit numrique, il faut associer un niveau de tension
(voltage) chaque chiffre. Imaginez que nous dcidions d'utiliser le systme dcimal pour construire un circuit
numrique. Il faut donc utiliser dix niveaux de tension. Ce qui nous donne un circuit trs compliqu. Par contre, le
systme binaire, ayant la plus faible base (b = 2), est le plus adapt. Il ncessite seulement deux niveaux de tension,
par exemple : 0V pour le digit 0 et 5V pour le digit 1. Pour cette raison, les 0 et les 1 sont les deux seuls symboles
du langage machine.

-5-

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

II-B - Le code ASCII


Le code ASCII (American Standard Code for Information Interchange) est un code alphanumrique utilis pour
l'change des informations entre deux ou plusieurs ordinateurs ou entre un ordinateur et ses priphriques.
Le processeur ne comprend pas la reprsentation humaine des caractres. Il utilise le codage ASCII (une squence
de 0 et 1), pour identifier les diffrents caractres alphanumriques. Par exemple, lorsque vous appuyez sur la touche
A de votre clavier, le processeur reoit son code ASCII.
Le codage ASCII standard utilise 7 bits pour reprsenter les caractres de l'alphabet (minuscule et majuscule), les
chiffres dcimaux, les caractres de ponctuation et les caractres de contrle :
Tableau 2 : La table ASCII standard

-6-

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

0
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
40
41
42

Dcimal

Caractre
NUL
SOH
STX
ETX
EOT
ENQ
ACK
BEL
BS
HT
LF
VT
ff
CR
SO
SI
DLE
DC1
DC2
DC3
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US
Space
!

#
$
%
&
'
(
)
*

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

Dcimal

Caractre

+
,
.
/
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U

Dcimal

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

Caractre

V
W
X
Y
Z
[
\
]
^
_

a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{
|
}
#
DEL

II-C - Le code BCD


Le code BCD, Binary Coded Decimal, est utilis pour coder des nombres d'une faon relativement proche de la
reprsentation humaine usuelle (en base 10). En BCD, les nombres sont reprsents en chiffres dcimaux et chacun
de ces chiffres est cod sur quatre bits :

-7-

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

0
1
2
3
4
5
6
7
8
9

Dcimal

0000
0001
0010
0011
0100
0101
0110
0111
1000
1001

BCD

Il est remarquable que les bits 0-3 de chaque code ASCII d'un chiffre dcimal sont gaux son code BCD.
D'autre part, la plupart des ordinateurs stockent les donnes dans des octets (d'une taille de 8 bits). Deux mthodes
communes permettent d'enregistrer les chiffres BCD de quatre bits dans un tel octet :

format non compact, Unpacked BCD : ignorer les quatre bits supplmentaires de chaque octet et leur
ajouter quatre bits identiques (0 ou 1) ;
format compact, Packed BCD : enregistrer deux chiffres (4 bits) par octet.

Pour illustrer, supposons qu'on stocke successivement les chiffres dcimaux 9 et 1 au format BCD :

format non compact : dcimal -> 1 9, binaire -> 0000 0001 0000 1001 ;
format compact : dcimal -> 1 9, binaire -> 0001 1001.

III - L'assemblage et l'dition de liens sous Linux


Le code suivant est celui du programme classique permettant d'afficher, sur la console, le message Hello, World ! :
1.
2. msg :
3. len = . - msg
4.
5.
6.
7.
8. _start :
9.
10.
11.
12.
13.
14.
15. exit :
16.
17.
18.

.data
.asciz "Hello, World !\n"
.bss
.text
.global _start
movl $msg,%ecx
movl $len,%edx
movl $1,%ebx
movl $4,%eax
int $0x80

# appel systme

movl $0,%ebx
movl $1,%eax
int $0x80

Le code est crit en assembleur GNU. Il utilise le jeu d'instructions d'un processeur de la famille x86-32. Nous en
discuterons dans la section 5. Dans cette section, nous allons juste montrer comment le faire tourner sur la machine.
Pour gnrer un fichier excutable partir du code source, nous utiliserons un programme dit assembleur et un
programme dit diteur de liens (linker). Sous un systme GNU/Linux, l'assembleur est le programme as et l'diteur
de liens est le programme ld (loader).
Le schma suivant montre les tapes suivre pour gnrer l'excutable :

-8-

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

L'assembleur as prend comme entre le fichier hello.s, ayant obligatoirement l'extension .s, pour gnrer le fichier
objet hello.o. son tour, l'diteur de liens va lier les diffrents morceaux du code objet et affecter chacun son
adresse d'excution (run-time address) et produire l'excutable. Celui-ci est au format ELF (Executable Linkable
Format). C'est le format des fichiers binaires utiliss par les systmes UNIX. C'est l'alternative l'ancien format a.out
(assembler output). Notre makefile contiendra les commandes (rules) suivantes :
1. hello : hello.o
2.
ld -o hello hello.o
3. hello.o : hello.s
4.
as -o hello.o hello.s
5.
6. clean :
7.
rm -fv hello.o

Important [1] : Le symbole global _start est le point d'entre par dfaut de l'diteur de liens.
Il symbolise l'adresse partir de laquelle le processeur commencera le fetch des instructions,
lorsque le programme sera charg en mmoire et excut. Si vous choisissez un nom de
symbole de votre choix comme point d'entre, vous devez passer l'option -e ou -entry l'diteur
de liens.

IV - Syntaxe de l'assembleur
Reprenons le code source du programme hello.s. Il contient trois sections : .data, .bss et .text.
Chaque section contient un ensemble de dclarations et (optionnellement) des lignes de commentaires.

IV-A - Les sections


Un programme crit en assembleur GNU peut tre divis en trois sections. Trois directives assembleur sont rserves
pour dclarer ces sections :
1
2
3

.text (read only) : la section du code. Elle contient les instructions et les constantes du programme. Un
programme assembleur doit contenir au moins la section .text ;
.data (read-write) : la section des donnes (data section). Elle dcrit comment allouer l'espace mmoire pour
les variables initialisables du programme (variables globales) ;
.bss (read-write) : contient les variables non initialises. Dans notre code, cette section est vide. On peut donc
l'liminer.
Important [2] : L'ordre des sections dans le code source n'est pas significatif. N'importe quelle
section peut tre vide !

-9-

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

IV-B - Les commentaires


Il existe deux mthodes pour commenter un code source. Les commentaires crits entre /* et */ peuvent occuper
plusieurs lignes. Un commentaire prfix par un # ne peut occuper qu'une seule ligne.

IV-C - Les dclarations


Les dclarations peuvent prendre quatre formats :
1.
2. label_1 :
3. label_2 :
4.
5.

.nom directive
.nom directive attribut
expression
instruction

op1 , op2 , ...

Une dclaration se termine par le caractre saut de ligne \n ou par le caractre ; .


Une dclaration peut commencer par une tiquette (label). Une tiquette peut tre suivie d'un symbole cl qui
dtermine le type de la dclaration. Si le symbole cl est prfix par un point, alors la dclaration est une directive
assembleur. Les attributs d'une directive peuvent tre un symbole prdfini, une constante ou une expression.

IV-D - Les symboles


Un symbole est une squence de caractres choisis parmi :
1
2
3

Les lettres de l'alphabet : a .. z, A .. Z ;


Les chiffres dcimaux : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ;
Les caractres : . $.
Important [3] : Un symbole ne doit jamais commencer par un chiffre. De plus, la casse est
significative. Ainsi, on peut utiliser les symboles msg, Msg et MSg dans le mme programme :
ils reprsentent des locations diffrentes dans la mmoire.
Important [4] : L'assembleur GNU rserve un ensemble de symboles cls pour les directives.

Une tiquette est un symbole suivi, immdiatement, du caractre : . Elle a deux usages :
1

Si l'tiquette est crite dans la section du code, alors le symbole reprsente une valeur du compteur
programme (le Program Counter ou le registre EIP du 80386).
On peut alors utiliser l'tiquette pour se rfrer dans le programme. On peut par exemple utiliser le nom du
symbole de l'tiquette comme oprande de l'instruction jmp pour transfrer le contrle la portion de code
situe l'adresse symbolise par l'tiquette ;
Si l'tiquette est crite dans la section de donnes (.data), alors le symbole reprsente une adresse dans
la zone mmoire des donnes. Par exemple, le symbole msg reprsente l'adresse du premier octet (code
ASCII) de la chane de caractres Hello, World ! .
Important [5] : Le nom du symbole d'une tiquette doit tre unique dans un programme.
Autrement dit, vous ne devez jamais utiliser le mme symbole pour reprsenter deux locations
(tiquettes) diffrentes. Les symboles locaux sont la seule exception.

- 10 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

Les symboles locaux


L'assembleur GNU propose dix noms de symboles locaux : 0 , 1 .. 9 . Vous pouvez dfinir un symbole local
en crivant une tiquette de la forme N : , avec N = 0, 1 .. 9. Pour se rfrer au dernier symbole N dfini, vous
pouvez, par exemple, spcifier Nb comme oprande de l'instruction jmp. De mme, pour se rfrer au premier
symbole N suivant, vous pouvez spcifier Nf comme oprande. La lettre b dans Nb est l'abrviation du
mot anglais backwards. La lettre f dans Nf est celle du mot forwards.
1:

##
##
jmp
jmp
##
##

1:

##
jmp
jmp

2:

1b
1f

1b
2f

##
##

2:

La premire instruction jmp va transfrer le contrle la portion de code situe l'adresse symbolise par la premire
tiquette 1 : . En excutant le deuxime et le troisime jmp, le processeur va commencer (immdiatement)
l'excution l'adresse symbolise par la deuxime tiquette 1 : . La quatrime instruction jmp va transfrer le
contrle la portion de code situe l'adresse symbolise par la premire tiquette 2 : (troisime tiquette dans
le code !).
Vous remarquez, dans l'exemple ci-dessus, qu'on a utilis le mme symbole 1 pour reprsenter deux locations
diffrentes. Ce qui est normalement interdit. Mais a fonctionnera quand mme. En effet, les noms des symboles
locaux sont juste des notations utilises temporairement par le compilateur et le programmeur. Ils seront transforms
en d'autres symboles avant d'tre utiliss par l'assembleur. Vous pouvez consulter le manuel de l'assembleur GNU
pour savoir comment ces symboles seront transforms.

IV-D-1 - Le symbole .
Le symbole spcial . peut tre utilis comme une rfrence une adresse au moment de l'assemblage.
Exemple :
Dans le programme de la section 3, avant d'excuter l'appel systme, le registre EDX doit contenir la taille (le nombre
de caractres) len du message. L'expression suivante permet de calculer prcisment len :
1. len = . - msg

Ici, le symbole . fait rfrence l'adresse de l'octet situ juste aprs le message dans la zone mmoire des
donnes. Donc, len est gale 14. C'est exactement le nombre d'octets de notre message.

IV-E - Les constantes


Les nombres entiers
Un nombre entier peut tre reprsent dans plusieurs systmes de numration. L'assembleur GNU en identifie
quatre : le binaire, le dcimal, l'octal et l'hexadcimal.

- 11 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

1
2
3
4

Un nombre binaire est un 0b ou 0B suivi de zro ou plusieurs chiffres binaires {0, 1}.
Exemple : 0b10011.
Un nombre octal est un 0 suivi de zro ou plusieurs chiffres octaux {0, 1, 2, 3, 4, 5, 6, 7}.
Exemple : 09122.
Un nombre dcimal ne doit pas commencer par 0. Il contient zro ou plusieurs chiffres dcimaux {0..9}.
Exemple : 97340.
Un nombre hexadcimal est un 0x ou 0X suivi de zro ou plusieurs chiffres hexadcimaux {0..9, A, B, C, D,
E, F}.
Exemple : 0x6FC9D.

Les caractres
Comme le montre le , chaque caractre est identifi par son code ASCII. Dans un code assembleur, on dfinit un
caractre en crivant son code ASCII appropri. En utilisant, la syntaxe de l'assembleur GNU, un caractre peut tre
crit comme une apostrophe suivie immdiatement de son symbole. Exemple :

'A est le code ASCII 65 de A ;


'9 dsigne le code ASCII 100 de 9.

Les chanes de caractres


Une chane de caractres (string) est une squence de caractres crite entre guillemets. Elle reprsente un tableau
contigu d'octets en mmoire. Exemple : Hello, World ! .
Important [6] : La manire d'obtenir des caractres spciaux dans une chane de caractres
est de les chapper en les faisant prcder d'un antislash \ .
Exemple :
Dans le programme de la section 3, nous avons chapp le caractre saut de ligne dans le message. Ainsi, nous
avons utilis un seul appel systme pour afficher la fois le message et effectuer le saut de ligne :
msg :

.asciz "Hello, World !\n"

Le caractre n, lorsqu'il est prfix par un antislash, est quivalent au code ASCII (10) du caractre saut de ligne.

IV-F - Les expressions


Une expression spcifie une adresse ou une valeur numrique. Une expression entire est un ou plusieurs arguments
dlimits par des oprateurs. Les arguments sont des symboles, des chiffres ou des sous-expressions. Une sousexpression est une expression crite entre deux parenthses. Les oprateurs peuvent tre des prfixes ou des
infixes :

Prfixes
Les oprateurs prfixes prennent un argument absolu. as propose deux oprateurs prfixes :

L'oprateur # complment bit--bit (bitwise not).


Exemple : 0b10001110 = 10001110 = 01110001 ;
L'oprateur ngation - (complment deux) : N = # N + 1.
Exemple : N = 142 = 0b10001110, 142 = 01110001 + 1 = 01110010.

- 12 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

Infixes
Un oprateur de type infixe prend deux arguments : #, /, %, <, <<, >, >>, +, , ==
Exemples d'expressions :
1.
2.
3.
4.

len = . - msg
SYSSIZE = 0x80000
SYSSEG = 0x1000
ENDSEG = SYSSEG + SYSSIZE

# ENDSEG = 0x81000

IV-G - Syntaxe des instructions 80386 (IA-32)


Les oprandes

Les registres : les oprandes de type registre doivent tre prfixs par un %.
Exemples : %eax, %ax, %al, %ah, %ebx, %ecx, %edx, %esp, %ebp, %esi, %edi
Les oprandes immdiats : les oprandes de ce type doivent tre prfixs par un $.
Exemples : $4, $0x79ff03C3, $0b10110, $07621, $msg
Les oprandes mmoire : lorsqu'un oprande rside dans le segment de donnes du programme, le
processeur doit calculer son adresse effective (EA : Effective Address) en se basant sur l'expression
suivante :
EA = base + scale * index + disp.
L'assembleur GNU utilise la syntaxe AT &T qui traduit l'expression prcdente en celle-ci :
EA = disp (base, index, scale)
avec :
- disp : un dplacement facultatif. disp peut tre un symbole ou un entier sign ;
- scale : un scalaire qui multiplie index. Il peut avoir la valeur 1, 2, 4 ou 6. Si le scale n'est pas spcifi, il est
substitu par 1 ;
- base : un registre 32 bits optionnel. Souvent, on utilise EBX et EBP (si l'oprande est dans la pile) comme
base ;
- index : un registre 32 bits optionnel. Souvent, on utilise ESI et EDI comme index.

La taille des oprandes peut tre code dans le dernier caractre de l'instruction : b indique une taille de 8 bits, w
indique une taille de 16 bits et l indique une taille de 32 bits.
Exemples :
1. movb $0x4f,%al
2. movw $0x4ffc,%ax
3. movl $0x9cff83ec,%eax

# 8-bit
# 16-bit
# 32-bit

L'ordre des oprandes


L'assembleur GNU utilise la syntaxe AT&T. Ainsi, une instruction mov doit tre crite comme suit :
1. mov source,destination

Cet ordre doit tre respect avec le reste des instructions : sub, add

Les instructions LJMP/LCALL


Les instructions LJMP (Long Jump) et LCALL (Long Call) permettent de transfrer le contrle un autre programme
situ dans un autre segment (autre que celui o elles sont crites !). La syntaxe de ces deux instructions est :
- 13 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

Ljmp
lcall

$segment,$offset
$segment,$offset

Le premier oprande de chaque instruction sera charg dans le registre CS et le deuxime sera charg dans le
registre EIP (ou IP en mode rel !).

IV-H - Les directives


Les directives sont des pseudo-oprations. Elles sont utilises pour simplifier, pour le programmeur, quelques
oprations complexes telles que l'allocation de la mmoire. Comme on l'a dit dans la section prcdente, le nom
d'une directive est un symbole cl prfix par un point.
Il existe plus de 70 directives dfinies par l'assembleur GNU. Les plus utilises sont :

.ascii string_1, string_2


Dfinit zro ou plusieurs chanes de caractres spares par des virgules.
1. msg1 :
2. bootMsg :

.ascii "Hello, World !\ n"


.ascii "Loading system ..."

.asciz string_1, string_2


Dfinit zro ou plusieurs chanes de caractres spares par des virgules et dont chacune se termine par le caractre
'\0.
Ainsi, ces deux dclarations sont quivalentes :
1. msg1 :
2. msg2 :

.ascii "Hello, World !\0"


.asciz "Hello, World !"

.byte expression_1, expression_2


Dfinit et initialise un tableau d'octets.
1. tab_byte :

.byte 23,'%,0xff,9,'\b

Le premier lment est le nombre 23 et il est situ l'adresse tab_byte, suivi par le code ASCII du caractre %

.word expression_1, expression_2


Dfinit et initialise un tableau de mots binaires (16 bits ou word).
1. descrp :
2.
3.
4.

.word
.word
.word
.word

0x07ff
0x0000
0x9200
0x00C0

Important [7] : Avec les processeurs de la famille x86, l'adresse d'un mot, double mot ou
d'un quad-mot (64 bits) est l'adresse de son LSB (Least Significant Byte). Ainsi, le quad-mot
0x00C09200000007ff se trouve l'adresse reprsente par descrp. C'est l'adresse de l'octet
0x07ff.

- 14 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

.quad expression_1, expression_2


Dfinit et initialise un tableau de quad-mots.
1. _gdt :
2.
3.
4.

.quad
.quad
.quad
.quad

0x0000000000000000
0x00c09A00000007ff
0x00C09200000007ff
0x0000000000000000

Un .quad est quivalent quatre .word successifs.

.int expression_1, expression_2


Dfinit et initialise un tableau d'entiers (quatre octets).
1. tab_int :

.int 3*6,16,190,-122

.long expression_1, expression_2


Dfinit et initialise un tableau d'entiers (quatre octets).
1. matrix3_3 :
2.
3.

.long 22,36,9
.long 10,91,0
.long 20,15,1

.fill repeat, size, value


Rserve repeat adresses contigus dans la mmoire et les charge avec les valeurs value de taille size.
1. idt :

.fill 256,8,0

Dfinit un tableau contenant 256 quad-mots l'adresse idt. Chaque lment du tableau contient zro comme valeur.

.org new-lc, fill


Avance le compteur location de la section courante l'adresse new-lc.
1.
2.
3. _start :
4.
5.

.text
.global

_start

.org 510,0
.word 0xAA55

Avance le compteur location (registre EIP) de la section texte (code segment) l'adresse 510 puis crit le mot 0xAA55.
Les octets 0..509 seront chargs par des zros.

.lcomm symbol, length


Dclare un symbole local et lui attribue length octets sans les initialiser.
1.
2.

.bss
.lcomm buffer,1024

- 15 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

Important [8] : La directive doit tre crite dans la section .bss.

.global symbol
Dclare un symbole global et visible pour l'diteur de liens ld.
1.

.global

_start,main

Par dfaut, l'diteur de liens ld reconnat le symbole global _start comme point d'entre l'dition de liens.
Important [9] : Un symbole global dclar dans un fichier source peut tre utilis dans un autre
fichier sans le redclarer.

.set symbol, expression et .equ symbol, expression


Ces deux directives sont similaires l'expression : symbol = expression.
1.
2.

.set SYSSIZE,0x80000
.equ SYSSEG,0x1000

V - Exemples de codes assembleur


V-A - Exemple 1 : tri bulles d'une liste d'entiers
Le programme tris.s utilise la mthode de tri bulles pour trier une liste d'entiers positifs entrs au clavier. La liste
trie sera, ensuite affiche, sur la console.

Dclaration des variables


1.
2. line :
3. space :
4. msg1 :
5. len1 = . - msg1
6. msg2 :
7. len2 = . - msg2
8.
9.
10.
11.

.data
.byte '\n
.byte 0x20
.ascii " << "
.ascii " >> "
.bss
.lcomm buffer,1024
.lcomm list,100
.lcomm stack,1024

buffer : une mmoire tampon pour stocker temporairement les caractres entrs au clavier ;
list : c'est un tableau d'entiers qui peut stocker 25 nombres entiers ;
stack : pour rserver 1024 octets dans la pile du programme.

tape 1 : entrer la liste d'entiers au clavier


1. msg_1 :
2.
movl $msg1,%ecx
3.
movl $len1,%edx
4.
movl $1,%ebx
5.
movl $4,%eax
6.
int $0x80
7.
8. # Saisir les entiers #############

##
##
##
##
##
##

ECX = l'adresse du message


EDX = la longueur du message en octets
EBX = file descriptor = 1 => standard output
Appel systme 4 : write
Interruption logicielle (Exception) ID = 0x80

- 16 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

9.
10. kybd :
11.
12.
13.
14.
15.
16.
17. # Compter
18.
19.
20. 1:
21.
22.
23.
24.

movl $buffer,%ecx
movl $1024,%edx
movl $0,%ebx
movl $3,%eax
int $0x80
les elements de la liste

##
##
##
##
##

ECX =
EDX =
EBX =
Appel

l'adresse du buffer
la taille du buffer en octets
file descriptor = 0 => standard input
systeme 3 : read

##

subl %esi,%esi
movl buffer(%esi),%ebx
incl %esi
cmp %bl,line
jne 1b

## EA = Scale * Index + Displacement

Les registres EAX, EBX, ECX, EDX doivent tre initialiss correctement avant l'excution de l'instruction int $0x80.
L'instruction int n gnre une exception (interruption logicielle) immdiatement aprs son excution.
L'ID (Interrupt Identifier) de l'exception est cod dans l'instruction (n). Le noyau Linux utilise le nombre 128 (0x80)
pour identifier les interruptions programmes des autres interruptions (NMI, Divide Error, Trap). Ainsi, l'instruction
int $0x80 (ou int $128) permet notre programme (application) d'accder au matriel (clavier, cran) en excutant
un appel systme. Le fichier /usr/include/asm-x86/unistd_32.h liste tous les appels systme Linux.
On va utiliser les appels systme 1, 3 et 4. Le registre EAX doit explicitement contenir le numro de l'appel systme.
galement, le registre EBX doit contenir le descripteur (file descriptor) du priphrique.
Les instructions 10..15 vont charger le buffer avec la liste des caractres (les entiers), en excutant l'appel systme
3 (read). Les entiers entrs au clavier doivent tre spars par un espace (seulement un !).
En excutant les instructions 17..24, le processeur va calculer le nombre de caractres entrs et le charger dans
le registre ESI.
Pour illustrer, supposons qu'on a entr la liste : 19 208 9756 101 229. Le buffer contient 18 caractres :

Le caractre saut de ligne doit tre entr la fin pour valider la saisie.

tape 2 : convertir les caractres du buffer


On a dit, au dbut de ce tutoriel, que l'ordinateur utilise le codage ASCII pour changer de l'information avec les
priphriques d'entre/sortie. Ainsi, et comme le montre le schma ci-dessus, la liste des entiers est reue par
l'ordinateur comme un flux (stream) de codes ASCII. Chaque code reprsente un caractre.
Donc, pour qu'on puisse effectuer des traitements (arithmtiques, comparaisons) sur des entiers, nous devons
d'abord convertir le buffer en une liste d'entiers. C'est l'objectif des lignes de code suivantes :
1.
2.

decl %esi
movl $0,%edi

## index dans le buffer


## index dans la liste
- 17 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

3.
4. new_elem :
5.
6.
7.
8.
9.
10.
11. new_digit :
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26. mult_10 :
27.
28.
29.
30.
31.
32.
33. if_space :
34.
35.
36.
37.
38. 1 :
39.

movl $10,%esp
movl $0,%ebp

## pour multiplier par 10


## compter le poids de chaque chiffre

subl %eax,%eax
subl %ecx,%ecx

## EAX = 0
## ECX = 0

addl
subl
decl
cmpl
jl
movb
cmp
je
subl
incl
cmpl
je
movl

%eax,%ecx
%eax,%eax
%esi
$0,%esi
1f
buffer(%esi),%al
$32,%al
if_space
$48,%eax
%ebp
$1,%ebp
new_digit
%ebp,%ebx

mul
decl
cmpl
jg
je

%esp
%ebx
$1,%ebx
mult_10
new_digit

movl %ecx,list(,%edi,4)
incl %edi
jmp new_elem

## ECX = ECX + EAX

## si ESI = 0
## charger un nouveau chiffre dans AL
## si buffer (%esi) = 32 (espace)
## chiffre decimal = ascii - 48

## multiplier EAX n (poids) fois par 10

## sauvegarder le contenu de ECX

movl %ecx,list(,%edi,4)

L'adresse effective d'un caractre dans le buffer est :


EA = disp + base = buffer + %esi = buffer(base, 0, 1) = buffer(%esi)
L'instruction mul utilise implicitement le registre EAX pour stocker le nombre multiplier. Le rsultat sera charg dans
EDX:EAX. Le seul oprande de l'instruction est le multipliant, qui est le contenu (10) du registre ESP dans notre cas.
tant donn le code ASCII d'un nombre dcimal, pour convertir ce code au nombre dcimal appropri, on doit
soustraire 48.
Exemple : ASCII(3) = 51 = 3 + 48 <==> 3 = ASCII(3) 48 (voir ).
n
D'autre part, un nombre dcimal est gal la somme de ses chiffres multiplis, chacun, par 10 . n est le poids de
chaque chiffre dans le nombre.
Donc, pour convertir un nombre du buffer reprsent par des caractres, on doit d'abord convertir ces caractres
en des nombres dcimaux. Puis, on doit appliquer la formule de la section II-A. Pour bien fixer les ides, on va
prendre comme exemple le nombre 229 (voir le schma ci-dessus). Pour le convertir, le processeur doit effectuer
le calcul suivant :
229 = (50 48) # 102 + (50 48) # 101 + (57 48) # 100 = 2 # 100 + 2 # 10 + 9 # 1
Pour convertir tous les lments de la liste, le processeur procde comme suit : tant que ESI > 0 :

- 18 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

charger l'octet l'adresse buffer(%esi) dans le registre AL et le comparer 32 (le code ASCII du caractre
SPACE) ;
si le contenu de AL est diffrent de 32, on soustrait 48 de AL. Ensuite, on multiplie le rsultat (AL - 48) n fois
par 10 (n est le poids du chiffre). Le rsultat de la multiplication sera charg dans EAX. On doit l'ajouter au
contenu de ECX, parce que la multiplication utilise implicitement les registres EAX et EDX. ECX doit tre
nettoy chaque fois qu'on rencontre un espace ;
un jmp if_space est excut si le contenu de AL est gal 32. ECX contient la somme de tous les chiffres
de chaque nombre aprs la multiplication par 10. Cette somme n'est autre que le code binaire (32 bits) du
nombre. On le sauvegarde l'adresse :
EA = disp + scale*index = list + %edi * 4 = list( 0 , index, 4 ) = list(,%edi,4)
Le scale est gal 4 parce que la taille d'un entier est 4 octets !

Finalement, Le registre EDI contient le nombre d'entiers de la nouvelle liste (list).

tape 3 : trier la liste


Voir le programme sort.c.

tape 4 : afficher la liste trie


Pour afficher un lment de la liste, l'ordinateur doit envoyer le code ASCII de chacun de ses chiffres au priphrique
de sortie standard (l'cran, fd = 1). D'autre part, les entiers de la liste sont stocks dans la mmoire au format binaire
(32 bits). On doit donc les convertir en un flux de caractres. Autrement dit, on doit calculer les codes ASCII (48..57)
de chacun de ces chiffres.
C'est l'objectif de cette portion de notre code :
1.
2.
3. 2 :
4.
5.
6.
7.
8. 3 :
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.

movl

%edi,%esi

movl
movl
movl

$10,%ebx
list(,%esi,4),%eax
$stack,%esp

movl $0,%edx
idivl %ebx
decl %esp
addl $48,%edx
movb %dl,(%esp)
cmpl $0,%eax
jg
3b
movl $stack,%edx
subl %esp,%edx
movl %esp,%ecx
movl $1,%ebx
movl $4,%eax
int
$0x80
movl $1,%edx
movl $space,%ecx
movl $1,%ebx
movl $4,%eax
int
$0x80
decl %esi
cmpl $0,%esi
jge
2b

Les proprits de la pile vont nous faciliter cette tche. Une conversion dcimal-dcimal (division entire par 10)
nous permettra d'extraire les chiffres de chaque entier. Pour avoir le code ASCII de chaque chiffre, on doit ajouter 48
son code obtenu par division entire (divl). Le schma suivant montre la conversion du nombre 269 :

- 19 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

Les instructions 22 et 23 permettent de calculer le nombre d'octets empils (12 octets pour le nombre 269). Le registre
EDX doit contenir ce nombre pour excuter l'appel systme. Le registre ECX pointe vers le TOS (Top Of Stack),
c'est--dire vers le premier chiffre. l'excution de l'appel systme, le processeur va afficher 2 puis 6 puis 9 (c'est
exactement 269) puis un espace.

V-B - Exemple 2 : les sous-programmes en assembleur


Le but de l'exemple somme.s est de montrer le passage des paramtres travers la pile un sous-programme. Une
telle opration doit suivre quelques rgles (conventions) pour rendre efficace la communication entre le programme
appelant et le sous-programme appel.

Le stack frame
Le processeur alloue, dynamiquement, un espace de stockage dans la pile pour chaque sous-programme. Cet espace
est appel stack frame. Il sera compltement libr au retour du sous-programme.

- 20 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

Un sous-programme utilise son propre stack frame pour stocker ses variables locales (variables automatiques en C,
qui seront perdues au retour du sous-programme !) durant son excution. Mme la fonction principale main() d'un
programme possde son propre stack frame !

Les tapes suivre


Les tapes ncessaires pour invoquer efficacement un sous-programme sont :

empiler les paramtres qu'on veut passer au sous-programme ;


appeler le sous-programme avec l'instruction call ;
enregistrer et mettre jour le registre EBP, dans le sous-programme :
1.
2.

push %ebp
movl %esp,%ebp

sauvegarder le contexte : empiler le contenu des registres du processeur pour ne pas les perdre durant
l'excution du sous-programme ;
excuter le sous-programme : au cours de cette tape, le registre ESP ne doit pas tre modifi. Le registre
EBP est utilis pour se rfrer aux donnes dans la pile ;
librer l'espace mmoire allou aux variables locales, en les dpilant de la pile ;

- 21 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

restaurer les anciennes valeurs des registres ;


restaurer la valeur de EBP : cette tape va dtruire le stack frame. crire ces deux lignes de code avant
l'instruction RET :
1.
2.

movl %ebp,%esp
pop %ebp

charger l'adresse de retour dans EIP : en excutant l'instruction RET. Tout simplement, elle va charger le
nouveau TOS dans le registre EIP ;
nettoyer la pile : en dpilant les paramtres empils pendant l'tape 1.

Le code somme.c montre comment effectuer un passage par adresse et un passage par valeur en langage C.
Cependant, le code somme.s montre ces deux mthodes de passage des paramtres en assembleur GNU.
Ce programme fait appel la fonction C printf(). L'exemple 3 va expliquer comment le faire.

V-C - Exemple 3 : interfacer du code assembleur et du langage C


Le programme date.s utilise les fonctions C standard scanf et printf pour saisir et afficher la date.
En langage C, les paramtres sont passs entre parenthses : printf(param,) et scanf(param,). Ce n'est pas le
cas en assembleur : les paramtres doivent tre passs travers la pile !
L'ordre des paramtres dans la pile est significatif. Ils doivent tre passs dans l'ordre suivant :

0(%ebp)
4(%ebp)
8(%ebp)
12(%ebp)
16(%ebp)
20(%ebp)

Adresse

Paramtre
l'ancien EBP
adresse de retour
adresse de format (pformat et sformat)
valeur/adresse de la variable jour
valeur/adresse de la variable mois
valeur/adresse de la variable an

Ainsi, les paramtres doivent tre empils dans l'ordre inverse celui dans lequel ils sont crits dans le prototype de
la fonction (parm1, parm2) ! Autrement dit, le dernier paramtre doit tre empil le premier et le premier paramtre
doit tre empil le dernier !
Les valeurs de retour de scanf et printf sont retenues dans le registre EAX.
Les tapes 3-9 d'appel des sous-programmes en assembleur sont invisibles, puisque nous ne sommes pas
responsables de l'implmentation de la fonction standard. On va juste y faire appel.

Le Makefile
Pour construire l'excutable partir d'un code source crit purement en assembleur, on a utilis les programmes as et
ld. C'est le cas de l'exemple 1. Mais pour assembler et faire l'dition de liens d'un programme assembleur invoquant
des fonctions C, on doit utiliser un compilateur. Sous Linux, le compilateur C est le programme gcc.
1. date : date.o
2.
gcc -gstabs -o date date.o
3.
4. date.o : date.s
5.
gcc -c -o date.o date.s
6. clean :
7.
rm -fv date date.o

- 22 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

Le compilateur gcc va transformer (compiler) notre code source (C + assembleur) en un code cible (code assembleur).
Puis il va faire appel as pour assembler et ld pour construire l'excutable. Le point d'entre de ld doit tre le
symbole global main.
Retour sur l'exemple 1
Le dossier exemple_3 contient un sous-dossier nomm tri. Le code source qu'il contient est une rcriture du
programme tri.s de l'exemple 1. On a modifi le programme par l'utilisation des deux fonctions C dfinies dans le
fichier func.c : saisir() et trier() :

la fonction saisir(), lorsqu'elle est appele, va demander l'utilisateur de saisir (scanf()) une liste d'entiers et
de les charger dans un tableau (list) d'entiers ;
la fonction trier() va trier la liste d'entiers en utilisant l'algorithme de tri bulles.

L'utilisation de ces deux fonctions, ainsi que l'utilisation de la fonction C standard printf() pour l'affichage, va nous
aider rduire la taille du programme, en liminant pas mal d'instructions assembleur. Notre code devient plus simple,
plus structur et donc plus comprhensible.

V-D - Exemple 4 : un programme d'amorage


Un secteur d'amorage (Boot Sector) est, gnralement, constitu des 512 premiers octets d'un support de stockage
(disquette, disque dur, CD/DVD, flash disk) qui peut contenir un programme d'amorage (Bootstrap program). Pour un
CD/DVD, une disquette ou un disque dur, un tel secteur n'est autre que le premier secteur (piste 0, tte 0, secteur 1).
D'autre part, un programme d'amorage est un programme 16 bits excutable, qui sera charg par le programme de
dmarrage du BIOS, dans la mmoire RAM durant la squence d'amorage de l'ordinateur.
travers cet exemple, on va montrer comment crire un tel programme et comment le faire tourner sur une machine
occupe par un processeur de la famille x86 (x86-32 ou x86-64).
Les codes sources des exemples cits dans cette section sont tlchargeables sur

cette page.

Le mode rel
Le 80386 a introduit aux processeurs de la famille x86 la capacit fonctionner en trois modes : mode protg,
mode virtuel et mode rel (ou mode 8086).
Le mode rel est le mode de fonctionnement du processeur immdiatement aprs la mise de l'ordinateur sous tension.
Dans ce mode, certains registres du processeur sont initialiss, par INTEL, des valeurs prdfinies. En outre, la
protection, les interruptions et la pagination sont dsactives et l'espace mmoire complet est disponible.
Ainsi, le processeur peut excuter uniquement des programmes 16 bits. Cet tat du processeur est adquat pour
excuter un programme d'amorage.

L'architecture interne du processeur en mode rel


En mode rel, un processeur de la famille x86 (x86-32 ou x86-64) excute uniquement des codes 16 bits conus
pour le 80286 et le 8086. Par consquent, son architecture interne est presque identique celle du 8086.
Le tableau suivant montre comment certains registres (le 30486, le Pentium I et tous les processeurs de la famille
P6) sont initialiss en mode rel :

- 23 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

EFLAGS
EIP
CS

Registre

Contenu

0x0002
0xFFF0
Slecteur : 0xF000
Base : 0xFFFF0000
Limite : 0xFFFF
Base : 0x00000000
Limite : 0xFFFF
Base : 0x00000000
Limite : 0xFFFF

DS,SS,ES,FS,GS
GDTR,IDTR

Pour plus de dtails, jetez un coup d'il sur le chapitre 9 de

ce document.

L'adressage de la mmoire en mode rel


Quelle que soit la taille de la mmoire de votre ordinateur, dans le mode rel le processeur peut adresser seulement
1 Mo + 64 Ko de RAM. Les 64 Ko sont utiliss pour adresser les priphriques d'entres/sorties. Le processeur peut,
alors, seulement manipuler des octets et des mots (16 bits). Cet espace mmoire peut tre localis dans n'importe
quelle zone de la mmoire physique, condition qu'elle ne soit pas rserve par INTEL.
En mode protg, un processeur de la famille x86 utilise la rgle suivante pour calculer une adresse physique :
Adresse linaire = Adresse physique = Base + Offset
On l'a appele adresse physique parce qu'en mode rel, la pagination sera dsactive.
D'autre part, en mode rel l'adresse physique est normalement calcule en utilisant cette rgle :
adresse logique = offset : base[segment selector]
adresse physique = base x 16 + offset
Cependant, la rinitialisation du processeur (RESET), l'adresse de base est gale 0xFFFF0000 (voir le tableau
ci-dessus). Ainsi, l'adresse de dpart est forme par l'addition de la valeur de l'adresse de base et le contenu du
registre EIP (offset). Ainsi :
Adresse physique = 0xFFFF0000 + 0xFFF0 = 0xFFFFFFF0
Juste aprs la mise sous tension de l'ordinateur, le processeur utilise la premire rgle pour localiser et excuter le
programme BIOS. Ensuite, le processeur va suivre la rgle normale pour la traduction des adresses en mode rel
(processeur 8086).
La premire instruction qui sera excute par le processeur, aprs RESET, devrait tre l'adresse physique
0xFFFFFFF0. Cette instruction va amener le processeur excuter une instruction JMP vers le programme BIOS.
Lorsque celui-ci prend le contrle, il commence par excuter les tests POST. Une fois ces tests passs avec succs,
le programme BIOS va chercher un priphrique amorable pour dmarrer le systme.

Le BIOS
Pour une machine compatible avec l'IBM PC, le BIOS (Basic Input Output System) est le premier programme
(microcode ou firmware) excut par le processeur (en mode rel) juste aprs la mise sous tension de l'ordinateur.

- 24 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

Le programme (les routines) BIOS est stock dans une mmoire non volatile (ROM) intgre la carte mre. Il a
deux fonctions principales :
1
2

Excuter les tests POST (Power-On Selft-test) : vrifier l'intgrit du programme BIOS lui-mme, tester la
RAM, tester et initialiser les autres priphriques de l'ordinateur, initialiser l'IVT (Interrupt Vector Table) ;
Chercher un priphrique amorable (bootable) pour dmarrer le systme (charger le noyau du systme
en mmoire). C'est en vrifiant, dans l'ordre, le secteur d'amorage de chaque priphrique connect
l'ordinateur et configur dans la liste (du BIOS) des priphriques d'amorage. Lorsque le BIOS rencontre un
secteur d'amorage, il charge en mmoire le programme stock dedans, et lui transfre le contrle.

Pour vrifier si un support de stockage est amorable ou non, le BIOS teste simplement les deux derniers octets
(octets 510 et 511) de son secteur d'amorage. Si ces deux octets contiennent la valeur 0xAA55 (Boot Signature),
alors le BIOS dduira que ce priphrique est amorable. Alors, il chargera les 512 octets du code l'adresse
physique 0x7C00 de la mmoire et lui transfrera le contrle (JMP 0x7C00).
Enfin, vous trouverez toutes les informations sur les BIOS sur

ce site.

L'IVT : Interrupt Vector Table


Le BIOS met la disposition de tout programme qui s'excute en mode rel des routines qui vont l'aider effectuer
quelques oprations compliques, comme l'accs au matriel de l'ordinateur. Ces routines sont appeles les services
ou encore les interruptions BIOS.
ce propos, un tableau de 256 entres est stock par le BIOS l'adresse absolue entre 0x0 et 0x3FF (le premier
Kb de la mmoire). Chaque entre de ce tableau est de quatre octets et contient deux adresses [segment :offset]
comme pointeurs vers une routine d'interruption.

- 25 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

Ces routines sont accessibles via l'instruction int n. Chaque interruption BIOS est identifie par un nombre n. Le
processeur multiplie par 4 le nombre n et utilise le rsultat (index) pour localiser, dans l'IVT, le vecteur d'interruption
appropri. Le premier mot (16 bits) sera charg dans le registre CS (segment) et le deuxime sera charg dans le
registre IP (offset).
Ainsi, le processeur va excuter la routine convenable.
Une entre dans ce tableau est note vecteur parce qu'il redirige le processeur pour excuter
une autre portion du code.

Un programme d'amorage minimal


Le code suivant est celui d'un programme d'amorage minimal :
1.
2.
3.
4.
5.
6. _start :
7.
8.

.code16
.data
.text
.global _start
.org 510,0
.word 0xaa55

Un support de stockage, dont le secteur d'amorage contient le binaire de ce programme, sera certainement
amorable. Mais, comme vous voyez, ce programme ne fera rien son excution (un cran noir et vide sera affich).
Il va juste rendre votre support de stockage amorable. La directive .org a dj t explique. La directive .code16
va demander l'assembleur d'assembler un code 16 bits (mode rel).
En fait, tout Linuxien a un programme d'amorage prt sur son ordinateur. C'est le stage1 du
chargeur de boot GRUB. Ce fichier est stock dans le rpertoire /usr/lib/grub/stage1. Son rle
est d'initialiser le processeur au dmarrage et de charger en mmoire le noyau GRUB (stage2).
Pour tester un programme d'amorage, vous pouvez utiliser une machine virtuelle au lieu de
redmarrer votre ordinateur plusieurs fois. Le logiciel VirtualBox, par exemple, vous permettra
d'en crer une.
En cas de problme de dmarrage d'une machine virtuelle sur un flash disk, visitez

cette page.

Exemple 1 : hello.s
1.
2.
3.
4. _start :
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18. msg :
19.
20.
21. signature

.code16
.text
.global_start
mov %cs,%ax
mov %ax,%ds
mov %ax,%es
mov %ax,%ss
mov $0x100,%ax
mov %ax,%sp
mov $0x2f,%bl
mov $0,%dh
mov $0,%dl
mov $0x1301,%ax
mov $msg,%bp
mov $13,%cx
int $0x10

# ax = 0x7c0
# ds = 0x7c0
# es = 0 x7c0
# ss = 0 x7c0
# 256 words dans la pile (512 octets)
# sp = 256 (TOS)
#
#
#
#
#

colonne 0
ligne 0
afficher une chane de caractres
offset du message ES:BP
taille du message

.asciz "hello, world !"


.org 510

- 26 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

22.

.word 0xaa55

Comme on l'a dit, au dmarrage de l'ordinateur ce programme sera charg dans la mmoire l'adresse 0x7C00 et
prendra le contrle. Le registre CS (base) sera charg avec la valeur 0x7C0 et le contenu de EIP (offset) sera 0.
Ainsi, le processeur commencera la recherche des instructions (fetch) et l'excution partir de l'adresse physique :
CS x 16 + EIP = 0x07C0 x 0x10 + 0x0000 = 0x7C00
Notre programme possde les mmes segments de donnes de pile et de code (DS = SS = ES = CS = 0x7C0).
On a utilis l'interruption 0x10 du BIOS pour afficher notre message. Une liste des interruptions est disponible sur
cette page.

Assemblage et dition de liens


Les commandes d'assemblage et d'dition de liens sont :
as -o hello.o hello.s
ld --oformat binary -Ttext 7c00 -Tdata 7c00 -o hello hello.o

On a utilis l'option -oformat pour spcifier l'diteur de liens le format binaire du fichier de sortie (hello). Le format
binaire doit tre choisi. Si on dite les liens sans utiliser cette option, la taille du fichier gnr dpassera 512 octets.
Quand on passe cette option l'diteur de liens, il va gnrer un fichier de sortie au format raw binary. Autrement dit,
il va gnrer un code machine ayant exactement une taille de 512 octets. galement, les options -Ttext et -Tdata
sont utilises pour indiquer l'diteur de liens que les sections de texte et de donnes doivent tre charges
l'adresse 0x7C00.
La commande suivante permet de dsassembler le fichier gnr :
objdump -b binary -mi8086 -D hello

L'option -b va spcifier le format de fichier d'entre (binaire). L'option -m va spcifier l'architecture pour laquelle on
va dsassembler. Nous avons spcifi l'architecture i8086.
Pour charger votre programme de boot sur le secteur d'amorage de votre flash disk, utilisez le programme
dd_rescue.
Exemple 2 : rtc.s
Dans cet exemple, nous allons crire un programme d'amorage qui, son excution, va lire l'horloge temps rel
(RTC) de l'ordinateur en utilisant l'interruption BIOS numro 0x1A et l'afficher au format hh:mm:ss.
l'excution de cette interruption, le processeur va lire l'horloge RTC et stocker sa valeur au format BCD compact
(Packed BCD), dans les registres CX et BX :

Pour afficher l'horloge, nous devons, d'abord, convertir chacun de ses chiffres cods au format BCD en son code
ASCII appropri. Le codage BCD utilise quatre bits pour coder chaque chiffre dcimal. Tandis que, le codage ASCII
utilise 8 bits (tendu) ou 7 bits (standard).

- 27 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

On a dit, au dbut de ce tutoriel (section II-C), que les bits 0-3 de chaque code ASCII d'un chiffre sont gaux son
code BCD. On va utiliser cette proprit pour convertir les codes BCD en des codes ASCII.
Le sous-programme bcd_to_ascii va raliser cette conversion (voir le code source rtc.s). Pour l'illustrer, nous allons
prendre un exemple. Supposons que l'horloge lue soit 23:45:37. Le contenu des registres CX et BX sera :

Nous allons expliquer comment convertir l'heure (h2h1) du format BCD au format ASCII.
tape 1 :
Dcalage logique (SHR) de 4 bits du contenu du registre AL :
SHR $4, %al : 0010 0011 4 = 0000 0010
tape 2 :
Addition de 48 :
0000 0010 + 00110000 = 110010 = 5010 = ASCII(2)
Ensuite, on charge le contenu de AL dans la mmoire l'adresse rtc(%si).
tape 3 :
Maintenant, nous allons convertir h2. Tout d'abord, on charge le contenu du registre CH dans AL. Ensuite, on ajuste
le contenu de AL avec l'instruction AAA :
AAA : 0010 0011 ==> 0000 0011
tape 4 :
Addition de 48 :
0000 0011 + 00110000 = 0011 0011 = 5110 = ASCII(3)
Ensuite, on charge le contenu de AL dans la mmoire l'adresse rtc(%si).
Les mmes tapes seront utilises pour convertir les minutes et les secondes. Utilisez les mmes commandes
(exemple 1) pour assembler, diter les liens et tester cet exemple.
Exemple 3 : int 0x13, AH = 0x42 : lecture tendue des secteurs.
Dans cet exemple, on va montrer comment utiliser la fonction 0x42 de l'interruption BIOS 0x13 pour lire (en mode
rel) des secteurs partir d'un priphrique de stockage de masse (un flash disk dans notre cas).
Le code source de l'exemple contient deux fichiers :

- 28 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

1
2

boot.s : c'est un programme d'amorage qui sera stock dans le premier secteur de notre priphrique
de stockage. Son rle est de lire le deuxime secteur du priphrique et de charger le programme stock
dedans (hello.s) en mmoire et, ensuite, lui transfrer le contrle ;
hello.s : le binaire de ce programme sera stock dans le deuxime secteur de notre priphrique de stockage
(juste aprs le secteur d'amorage). son excution, ce programme va afficher un message l'cran en
utilisant l'interruption BIOS 0x10.

En fait, le BIOS propose une autre fonction de l'interruption 0x13 pour lire des secteurs partir d'un priphrique de
stockage. C'est la fonction classique numro 0x2 (AH = 0x2).
Cette fonction est trs complique parce qu'elle utilise l'adressage CHS (Cylinder/Head/Sector) pour localiser les
secteurs lire. De plus, elle limite le nombre de cylindres (pas plus de 1024 cylindres) et le nombre de secteurs (pas
plus de 63 secteurs) lire.
Le nombre de cylindres (d'un disque dur ou d'une disquette) est gal au nombre de pistes (track)
par plateau.
Par contre, la fonction 0x42 de l'interruption BIOS est trs simple utiliser et permet de lire n'importe quel secteur
du priphrique. Cette fonction traite le priphrique comme un tableau contigu de secteurs (512 octets), o chaque
lment (secteur) est identifi uniquement par son numro (index) ! Cette mthode d'adressage des secteurs de
disque dur est souvent nomme Logical Block Addressing, LBA.
Le tableau suivant liste les paramtres qu'on doit spcifier pour l'interruption 0x13 :
AL
DL

0x42, numro de la fonction


index du priphrique de stockage (flash
disk par exemple)
[segment :offset] pointeur vers le DAP : Disk
Address Packet

DS:SI

L'index de priphrique de stockage sera charg automatiquement par le BIOS, au dmarrage, dans le registre
DL. D'autre part, le DAP est une structure de donnes qu'on doit spcifier l'interruption 0x13. Elle doit contenir
exactement les informations suivantes :

0x0
0x1
0x2 - 0x3
0x4 .. 0x7

Offset

0x8 .. 0xf

1 octet
1 octet
2 octets
4 octets

Taille

8 octets

Description
La taille du DAP = 16 octets
inutilis, doit tre gal 0
nombre de secteurs lire
[segment :offset] : un pointeur
vers la zone mmoire dans
laquelle on va stocker les
donnes lues
le numro du premier secteur
64
qu'on va lire : 0 .. (2 1)

16
Ainsi, la fonction 0x42 peut lire 2 secteurs la fois (nombre de secteurs lire) et peut traiter un disque dur (par
64
exemple) de taille 2 # 512 octets ! Et je vous laisse faire le calcul.
En cas d'erreur de lecture, le bit CF du registre EFLAGS sera mis 1. Une instruction JC (Jump short if carry) peut
tre utilise pour traiter l'erreur, en rptant la lecture par exemple.
Le code de notre programme d'amorage (boot.s) est le suivant :
.code16
- 29 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/

Introduction l'Assembleur GNU par Issam Abdallah

.text
.global _start
_start :
mov
mov
mov
mov
mov
movb
movw
int
ljmp

%cs,%ax
%ax,%ds
%ax,%es
%ax,%ss
$0x100,%sp
$0x42,%ah
$dap,%si
$0x13
$0x900,$0x0

#
#
#
#
#
#

DS = 0 x7c0
ES = 0 x7c0
SS = 0 x7c0
TOS = 256 (512 octets)
fonction 0x42 : lecture tendue des secteurs
SI = dap : pointeur vers la structure

# JMP vers [segment:offset] =


# 0x900 x 0x16 + 0x0 = 0x9000

## DAP : Disk Address Packet


dap :
.byte
0x10
# taille de dap = 16 octets
.byte
0x0
# inutilis : gale 0
.word
0x1
# nombre de secteurs lire
## buffer = [ segment:offset] : mmoire vers
## laquelle on va transfrer le contenu des secteurs lus
.word
0x0000
# offset
.word
0x900
# segment
.quad
0x1
# secteur2 : l'index du premier secteur
.org
.word

510
0xaa55

son excution, notre programme va lire le deuxime secteur du priphrique de stockage (secteur numro 1) et
charger les donnes stockes dedans (binaire du programme hello.s) dans la mmoire l'adresse physique 0x9000 :
segment :offset = 0x0900 :0x0000
adresse physique = 0x0900 * 0x10 + 0x0000 = 0x9000
L'instruction ljmp va transfrer le contrle au programme situ cette adresse (voir section IV-G).

VI - Rfrences

Intel 80386 Programmer's Reference Manual


le manuel de l'assembleur GNU
le manuel du linker ld
PC Assembly Language, par Paul A. Carter.

VII - Remerciements
Je remercie Obsidian pour sa relecture technique, ainsi que zoom61 et f-leb pour leur relecture orthographique.

- 30 -

Les sources prsentes sur cette page sont libres de droits et vous pouvez les utiliser votre convenance. Par contre, la page de
prsentation constitue une uvre intellectuelle protge par les droits d'auteur. Copyright 2014 Issam Abdallah. Aucune reproduction,
mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation
expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://asm.developpez.com/cours/gas/