Petit tutorial assambleur (GAS)
Contents
Les flags du regitre status
+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+---+ | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bits +--------------------------------------------------------------------- | -- | -- | -- | -- | O | D | I | T | S | Z | - | A | - | P | - | C | Flags +----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+---+
CF : carry flag.
PF : parity flag. Indique la parité du bit le plus faible du dernier résultat mathématique.
AF : adjust flag.
ZF: Zero flag. Est mis à si le le résultat de la dernière opération arithmétique vaut 0.
SF: sign (ou negative) flag. Indique si le bit de poid fort a été changé lors de la dernière operation mathématique.
TF: trap flag. Indique que le système doit s'interrompre après l'execution d'une instruction.
IF: interrupt flag. Indique que le système doit gérer les interruptions matérielles.
DF: direction flag. indique la direction de traitement (droite -> gauche ou gauche -> droite) de chaînes.
OF: overflow flag. Indique si la dernière opération s'est terminée par un dépassement de capacité.
Les registres (GPR)
- eax : accumule les resultats(accumulator)
- ebp : stack base pointer. Pointe sur la base de la pile.Pointe sur la base de la pile.
- ebx : pointe sur les données du segment (DS).
- ecx : compteur pour les boucles(counter)
- edi : pointe sur es données de l'adresse contenu dans DS. Pointeur destination pour la manipulation des chaînes (destination)
- edx : pointeur entrées/sorties (data)
- eip : instruction pointer. Indique la prochaine instruction à executer. Lors des sauts (jump, call), sa valeur est sauvegardée sur la pile *avant* l'execution du saut.
- esi : pointe sur les données de l'adresse contenu dans DS. Pointeur source pour les manipulation des chaînes(source)
- esp : top stack pointer. Pointe sur le dernier element de la pile, c'est à dire l'element le plus récent déposé.
Les registres sont en 32 bits. Il est possible d'utiliser les registes eax, ecx, edx et ebx au format 16 bits. Dans ce cas, l'accès ce fait en supprimant le prefix e. Enfin, ces registres 16 bits sont également accessible en mode 8 bits en remplaçant le suffix x par l ou h. h correspondant aux bits de poid fort(msb) et l aux bits de poid faible(lsb).
+-------------------------------------------------------------------------------------------+ | Accumulator | Counter | Data | Base | Stack Pointer | Base Pointer | Source | Destination | +----+-------------------------------------------------------------------------------------------------+ | 8 (lsb) | al | cl | dl | bl | N/A | N/A | N/A | N/A | +----------+-------------------------------------------------------------------------------------------+ | 8 (msb) | ah | ch | dh | bh | N/A | N/A | N/A | N/A | +----------+-------------------------------------------------------------------------------------------+ | 16 | ax | cx | dx | bx | sp | bp | si | di | +----------+-------------------------------------------------------------------------------------------+ | 32 | eax | ecx | eax | ebx | esp | ebp | esi | edi | +----------+-------------------------------------------------------------------------------------------+
Les segments
- CS : code
- DS : data
- SS : pile
- ES : data
- FS : data
- GS : data
Appels de fonctions
Appel d'une fonction
- Lors de l'appel d'une fonction, les opérations suitvantes sont effectuées:
- paramètres devant être passés à la fonction sont sauvegardés sur la pile (de droite à gauche).
- La valeur de %eip est sauvegardée sur la pile, mais la valeur de %ebp n'est pas modifiée.
- %eip est modifié pour pointer vers la nouvelle addresse à executer
Début de la nouvelle fonction
Une fois arrivée dans la nouvelle fonction, il faut une nouvelle pile locale. Les opérations suivantes sont effectuées à l'entrée de la fonction:
- %ebp est sauvegardée sur la pile (push %ebp)
- %ebp est modifié pour le faire pointer à la valeur de %esp (mov %esp %ebp)
- $ebp: valeur de ebp avant l'entrée dans la fonction
- $ebp+4: adresse de retour vers la fonction mère.
- $ebp+8 : premier argument destinée à la fonction
Exemples
Etat de la pile lors de l'appelle d'une procédure avec 2 arguments
Etat de la pile |
offset ebp |
offset esp |
Variables locales de la procédure source |
16(%ebp) |
24(%esp) |
2ème argument transmis à la procédure appellée |
12(%ebp) |
20(%esp) |
1er argument transmis à la procédure appellée |
8 (%ebp) |
16(%esp) |
addresse de retour vers la procédure mère |
4(%ebp) |
12(%esp) |
sauvegarde de ebp |
0(%ebp) |
8(%esp) |
1ère variable locale de la procédure |
-4(%ebp) |
4(%esp) |
2ème variable locale de la procédure |
-8(%ebp) |
0(%esp) |
Les instructions
Les instruction pour Gnu Assembeur (GAS) utilise la norme AT&T et sous la forme:
opcode: code[b/w/l] src, dest. Avec b pour byte, w pour word et l pour long.
- registre: %reg
- accès mémoire: section:addr(base, index, scale). Le calcul se fait suivant la formule val = base + index * scale + addr, avec scale valant 1, 2, 4 ou 8.
Référence mnemonic
mov src, dst: déplace des données vers/depuis les régistres et la mémoire.
Examples:
- mov $4, %eax : charge la constante 4 dans eax.
- mov %eax, %ebx : copie eax dans ebx
- mov %ebx, 123 : copie de ebx vers l'adresse 123.
push src : insere un objet (regsitre, valeur) vers la pile.
- Examples:
- push %ebp : copie la valeur de ebp sur la pile
- Examples:
pop dest : dépile la première valeur vers de la pile.
- Examples:
- pop %ebp : dépile la valeur la plus récente de la pile vers ebp.
- Examples:
- pop dest est équivalent aux instructions:
- mov (%esp),dest add $4,%esp
call func : appelle d'une sous routine.
ret : quitte la sous routine.
add src,dest : additionne src et dest et place le résultat dans dest.
- Examples:
- add src, dest : dest = dest + src
- add %ebx,%eax : eax = eax + ebx
- Examples:
mul src : sauvegarde le résultat de la multiplication de eax et src dans eax.
- Examples:
- mul src : eax = eax * src
- mul %ebx : eax = eax * ebx
- Examples:
jmp label: effectue un saut vers le label label.
cmp A, B, test A B : compare 2 valeurs et met à jour les flags pouvant être utilisés pour des sauts conditionnels par les instructions. Dans le cas de cmp, la comparaison s'effectue par la soustraction de A à B (B-A). Dans le cas de test la comparaison s'effectue par and entre A et B. Il est possible d'utiliser les saut conditionnels suiçvants:
jl label : effectue le saut vers le label si B < A
jle label : effectue le saut vers le label si B <= A
jge label : effectue le saut vers le label si B > A (Z
jg label : effectue le saut vers le label si B >= A
je label : effectue le saut vers le label si B = A
jne label : effectue le saut vers le label si B != A
jz label : effectue le saut vers le label si le flag Zero est à 1. (indentique à je).
jnz label : effectue le saut vers le label si le flag Zero est à 0. (indentique à jne).
- exemples:
cmp $10,%eax ; je OK: effectue le saut vers le label OK si eax est égale à 10.
- exemples:
pense bêtes GDB
Passer des arguments à l'executable débuggé: set args arg1
Afficher la valeur d'une addresse mémoire: x addr. Par exemple, pour afficher l'addresse du premier élement de pile : x/a $esp.
Modifier une valeur : set {type} addr=valeur