Chapitre 2. Registres et structures

Table des matières
2.1. Les registres de travail
2.2. Les registres d'offset
2.3. Le registre des drapeaux
2.4. Les structures de contrôle
2.4.1. Boucle WHILE
2.4.2. Boucle DO..WHILE
2.4.3. Boucle FOR
2.5. Copie de chaîne

Dans le Chapitre 1 nous avions laissé de côté la description des registres du processeur et leur rôle respectif. Nous allons ici rapidement aborder le sujet — juste assez pour pouvoir nous débrouiller par la suite.

Tout d'abord, précisons que sous GNU/Linux, contrairement à ce qui se passait sous DOS, nous n'avons pas vraiment besoin de nous encombrer avec la notion de « segment ». En effet, bien que les segments soient évidemment présents, leur taille peut aller jusqu'à 4Go... Donc, nous n'aurons plus à jouer avec cs, ds et es constamment :-) Penchons-nous plutôt sur ce qui nous touche de près : les registres du microprocesseur. Les registres qui nous intéressent particulièrement sont :

2.1. Les registres de travail

Comme nous l'indiquions brièvement dans le Chapitre 1, ces registres (sur 32 bits depuis le 80386) peuvent être décomposés en plusieurs sous-registres. Vous serez sûrement surpris de constater qu'on ne peut atteindre directement les 16 bits de poids fort des registres e*x, et que les registres *x ne représentent que les 16 bits de poids faible[1]. Si cela vous dérange, vous pourrez toujours utiliser l'instruction movzx qui permet d'étendre *x dans e*x.

Tableau 2-1. Découpage d'un registre de travail

Registre(s)Taille
eax32 bits
ax16 bits
ahal8 bits chacun

On voit que e*x (32 bits) est composé de *x (16 bits de poids faible) lui-même composé de *h (8 bits de poids fort) et *l (8 bits de poids faible).

Tableau 2-2. Rôles des registres de travail

RegistreNomDescription
eaxAccumulateur Sert aux opérations mathématiques mais aussi à la transmission des numéros de fonctions à appeler lorsqu'on se sert de l'interruption système 0x80 et au renvoi des résultats dans les fonctions (que nous aborderons au Chapitre 3). Lorsque vous devez utiliser un registre pour une opération quelconque et que vous ne savez pas lequel utiliser, privilégiez celui-ci — c'est le plus optimisé au niveau de la rapidité d'exécution des opérations.
ebxBase Utilisé pour l'adressage indirect
ecxCompteur Ce registre est utilisé chaque fois que l'assembleur a besoin d'un « compteur ». Nous devrons l'utiliser lorsque nous mettrons en place des boucles via l'instruction loop ou encore lorsque nous ferons des transferts de données entre esi et edi.
edxDonnéesSert aussi pour quelques opérations mathématiques.

Même si chacun de ces registres est optimisé ou utilisé pour certaines opérations, ils peuvent être employés à toutes fins utiles. Il suffit juste de savoir, par exemple, que c'est le registre ecx et lui seul qui sera utilisé et décrémenté par l'instruction movsd dans le cas de la copie d'une chaîne[2]. Cela ne veut pas dire que ecx est dédié à cette tâche de « compteur », mais juste qu'il est optimisé par le processeur pour cette tâche et utilisé en tant que tel par d'autres instructions.

Notes

[1]

On désigne par « bits de poids faible » les bits situés le plus à droite, et « bits de poid fort » ceux situés le plus a gauche. Par exemple, si nous travaillons avec un registre de 16 bits et que nous y mettons la valeur hexadécimale 0x4d50 : mov ax,4d50h, al contiendra 0x50 et ah contiendra 0x4d.

[2]

nous aborderons cet exemple plus loin lorsque nous parlerons des boucles.