Les registres: %eax %ebx %ecx %edx %esi %edi %ebp %esp
.
Ils contiennent tous un entier de 32 bits (4 octets), qui peut aussi être vu
comme une adresse. Le registre %esp
est spécial, et pointe sur le
sommet de pile; il est modifié par les instructions pushl
,
popl
, call
, ret
notamment.
Il y a aussi d’autres registres que l’on ne peut pas manipuler directement.
(L’instruction info registers
sous gdb
ou ddd
vous les
montrera.) Le plus important est eip
, le compteur de programme:
il contient en permanence l’adresse de la prochaine instruction à
exécuter.
1em
addl
<source>, <dest>.......<dest>=
<dest>+
<source> (addition)addl $1, %eax
ajoute 1 au registre %eax
.addl $4, %esp
dépile un élément de 4 octets de la pile.addl %eax, (%ebx, %edi, 4)
ajoute le contenu de %eax
à
la case mémoire à l’adresse %ebx
+ 4*%edi
. (Imaginez
que %ebx
est l’adresse de début d’un tableau a
, %edi
est un index i
, ceci stocke %eax
dans a[i]
.)
andl
<source>, <dest>.......<dest>=
<dest>&
<source> (et
bit à bit)
call
<dest>.......appel de procédure à l’adresse <dest> pushl $
a, où a est l’adresse juste
après l’instruction call
(l’adresse de retour), suivi de
jmp
<dest>.call printf
appelle la fonction printf
.call *%eax
(appel indirect) appelle la fonction dont l’adresse est dans le
registre %eax
. Noter qu’il y a une irrégularité dans la
syntaxe, on écrit call *%eax
et non call (%eax)
.
cltd
.......conversion 32 bits -> 64 bits %eax
en un nombre sur 64
bits stocké à cheval entre %edx
et %eax
. %eax
n’est pas modifié; %edx
est mis à 0 si
%eax
est positif ou nul, à −1 sinon. idivl
.
cmp
<source>, <dest>.......comparaison je
, jge
, etc.). À noter que la comparaison
est faite dans le sens inverse de celui qu’on attendrait. Par exemple,
cmp
<source>, <dest> suivi d’un jge
(“jump if greater than or
equal to”), va effectuer le saut si <dest>≥<source>: on compare <dest> à
<source>, et non le contraire.
idivl
<dest>.......division entière et reste %edx
et %eax
(cf.
cltd
) par le nombre 32 bits <dest>. Retourne le quotient en
%eax
, le reste en %edx
.
imull
<source>, <dest>.......multiplie <dest> par <source>,
résultat dans <dest>
jmp
<dest>.......saut inconditionnel: eip
=<dest>
je
<dest>.......saut conditionnelcmp
) a conclu que <dest>=<source>, continue avec le flot normal du
programme sinon.
jg
<dest>.......saut conditionnelcmp
) a conclu que <dest>><source>, continue avec le flot normal du
programme sinon.
jge
<dest>.......saut conditionnelcmp
) a conclu que <dest>≥<source>, continue avec le flot normal du
programme sinon.
jl
<dest>.......saut conditionnelcmp
) a conclu que <dest><<source>, continue avec le flot normal du
programme sinon.
jle
<dest>.......saut conditionnelcmp
) a conclu que <dest>≤<source>, continue avec le flot normal du
programme sinon.
leal
<source>, <dest>.......chargement d’adresse effective=&
<source>.
movl
<source>, <dest>.......transfert=
<source>.movl %esp, %ebp
sauvegarde le pointeur de pile %esp
dans
le registre %ebp
.movl %eax, 12(%ebp)
stocke le contenu de %eax
dans les
quatre octets commençant à %ebp
+12.movl (%ebx, %edi, 4), %eax
lit le contenu de
la case mémoire à l’adresse %ebx
+ 4*%edi
, et le met
dans %eax
. (Imaginez
que %ebx
est l’adresse de début d’un tableau a
, %edi
est un index i
, ceci stocke a[i]
dans %eax
.)
negl
<dest>.......<dest>=-
<dest>(opposé)
notl
<dest>.......<dest>=~
<dest>(non bit à bit)
orl
<source>, <dest>.......<dest>=
<dest>|
<source> (ou bit à bit)
popl
<dest>.......dépilementmovl (%esp),
<dest> suivi de
addl $4, %esp
.popl %ebp
récupère une ancienne valeur de %ebp
sauvegardée sur la pile, typiquement, par pushl
.
pushl
<source>.......empilementmovl
<source>, -4(%esp)
suivi de
subl $4, %esp
.pushl %ebp
sauvegarde la valeur de %ebp
, qui sera
rechargée plus tard par popl
.pushl
<source> permet aussi d’empiler les arguments successifs
d’une fonction. (Note: pour appeler une fonction C comme printf
par exemple, il faut empiler les arguments en commençant par celui de droite.)
ret
.......retour de procédurepopl eip
... si cette instruction existait (il n’y
a pas de mode d’adressage permettant de manipuler eip
directement).
subl
<source>, <dest>.......<dest>=
<dest>-
<source>(soustraction)subl $1, %eax
retire 1 du registre %eax
.subl $4, %esp
alloue de la place pour un nouvel élément de
4 octets dans la pile.
xorl
<source>, <dest>.......<dest>=
<dest>^
<source> (ou exclusif bit à bit)