Programmation Assembleur/x86/Les flags


Les flags (ou indicateurs en français) sont des bits stockés dans un registre spécifique nommé F, FLAGS ou EFLAGS. Chaque bit correspond à différents tests sur les derniers opérandes utilisés durant la dernière opération effectuée (opération arithmétique, comparaison, ...).

Programmation Assembleur/x86
Modifier ce modèle

L'opération de comparaison de deux valeurs effectue une soustraction entre les deux opérandes sans stocker le résultat. Le positionnement des indicateurs donne le résultat de la comparaison.

Ces différents indicateurs ont tous un nom court de deux lettres dont la deuxième est F signifiant Flag.

Le registre F

modifier

Le registre EFLAGS (extended flags) contient un mot de 32 bits qui sont les suivants :

bit   31  30  29  28  27  26  25  24  23  22  21  20  19  18  17  16
flag   0   0   0   0   0   0   0   0   0   0  ID  VIP VIF AC  VM  RF
bit   15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
flag   0  NT   IOPL   OF  DF  IF  TF  SF  ZF   0  AF   0  PF   1  CF

Le registre FLAGS correspond aux 16 bits de poids faibles du registre EFLAGS.

Le registre RFLAGS contient un double mot de 64 bits dont les 32 bits de poids faibles contiennent EFLAGS.

Zero Flag (ZF)

modifier

Cet indicateur est positionné à 1 si les deux opérandes utilisés sont égaux, sinon positionné à 0. Son nom vient de la différence nulle entre les deux opérandes.

Overflow Flag (OF)

modifier

Cet indicateur est positionné à 1 si le dernier résultat a débordé de la taille du registre,sinon à 0 .

Cet indicateur est utilisé par les sauts conditionnels :

  • L'instruction JO permet de poursuivre l'exécution à l'adresse indiquée si l'indicateur OF est à 1 (Jump if Overflow),
  • L'instruction JNO permet de poursuivre l'exécution à l'adresse indiquée si l'indicateur OF est à 0 (Jump if No Overflow),

Quand cet indicateur est à 1, l'instruction INTO (INTerrupt if Overflow) appelle l'interruption 4 (débordement). S'il est à 0, l'instruction INTO ne fait rien.

Carry Flag (CF)

modifier

Cet indicateur est positionné à 1 si la dernière opération a générée une retenue (mode non signé),sinon à 0 .

Trois instructions permettent de modifier cet indicateur :

  • L'instruction CLC (CLear Carry) positionne l'indicateur CF à 0 (pas de retenue),
  • L'instruction STC (SeT Carry) positionne l'indicateur CF à 1 (retenue),
  • L'instruction CMC (CompleMent Carry) change l'indicateur CF à 0 s'il valait 1, ou à 1 s'il valait 0.

Cet indicateur est utilisé par les sauts conditionnels (JC, JNC, JB, JNB, ...).

Il est également pris en compte par les instructions arithmétiques suivantes :

  • L'instruction ADC (ADd with Carry) ajoute la valeur de l'indicateur à la somme des opérandes,
  • L'instruction SBB (SuBstract with Borrow) soustrait la valeur de l'indicateur à la différence entre les opérandes.

Auxiliary carry Flag (AF)

modifier

Cet indicateur est positionné à 1 si la dernière opération a généré une retenue du bit numéro 3 vers le bit numéro 4, à 0 sinon.

Sign Flag (SF)

modifier

Cet indicateur est positionné à 1 si la dernière opération a généré un résultat négatif, à 0 s'il est positif ou nul.

Parity Flag (PF)

modifier

Cet indicateur est positionné à 1 si dans les 8 bits de poids faible du résultat de la dernière opération, le nombre de bits à 1 est pair, à 0 si ce nombre est impair.

Cet indicateur est utile pour la détermination du bit de parité pour la transmission octet par octet.

Interrupt Flag (IF)

modifier

Cet indicateur est positionné à 1 si les interruptions sont autorisées, à 0 sinon.

Deux instructions permettent de modifier cet indicateur :

  • L'instruction CLI (CLear Interrupt) positionne l'indicateur IF à 0 (interruptions ignorées),
  • L'instruction STI (SeT Interrupt) positionne l'indicateur IF à 1 (interruptions autorisées).

Direction Flag (DF)

modifier

Cet indicateur est positionné à 1 si le transfert de données se fait en décrémentant les offsets, à 0 sinon (incrémentation des offsets). Cet indicateur modifie le comportement des instructions de chaînes d'octets (STOS*, LODS*, CMPS*, SCAS*, MOVS*).

Deux instructions permettent de modifier cet indicateur :

  • L'instruction CLD (CLear Direction) positionne l'indicateur DF à 0 (UP : incrémentation des offsets),
  • L'instruction STD (SeT Direction) positionne l'indicateur DF à 1 (DOWN : décrémentation des offsets), mnémotechnique : SeT Down.

Trap Flag (TF)

modifier

Cet indicateur est positionné à 1 pour exécuter les instructions en mode pas à pas.

Quand cet indicateur est activé, avant chaque instruction, le processeur appelle l'interruption 1 (INT 1). Cette interruption est utilisée par les débogueurs quand le mode pas à pas est activé :

  1. Le débogueur défini le vecteur pour l'interruption 1 pointant vers une routine exécutée après chaque instruction ;
  2. Puis l'indicateur Trap Flag (TF) est mis à 1 (en utilisant la pile et l'instruction POPF).

La routine de débogueur est alors exécutée après chaque instruction ce qui lui permet de :

  • tracer la valeur des registres après chaque instruction,
  • décrémenter un compteur d'instructions et interrompre l'exécution quand le compteur atteint zéro,
  • détecter quand une condition complexe arrive et interrompre l'exécution.

Quand la condition d'interruption de l'exécution est d'atteindre une adresse particulière, une méthode plus efficace est de placer un point d'arrêt.

Accès au registre des indicateurs

modifier

Les indicateurs sont utilisés par les instructions de saut conditionnels.

Il est possible d'accéder au registre des indicateurs de deux manières :

  • En utilisant la pile :
    • Le registre des indicateurs est copié sur la pile (empilé) par l'instruction PUSHF,
    • Il est lu depuis la pile (dépilé) par l'instruction POPF.
  • En passant par le registre AH :
    • L'instruction LAHF charge les 8 bits de poids faible du registre des indicateurs vers le registre AH,
    • L'instruction SAHF copie le contenu du registre AH dans les 8 bits de poids faible du registre des indicateurs.

L'instruction non documentée SETALC initialise le registre AL selon la valeur de l'indicateur de retenue (CF) en y stockant 0xFF si CF vaut 1, ou 0x00 sinon.