Introduction à la programmation en assembleur (processeurs 64 bits de la famille 80x86)
2.3. Débordements

Comment le programmeur peut-il savoir si le calcul a donné un résultat valide ?

En effet, si l'on ajoute 1 à 255 sur un octet, pour le microprocesseur, le résultat (invalide) est 0. De même, toujours sur un octet, -128 - 1 donne 127 (0b10000000 – 0b1 = 0b01111111).

Explication

En plus des registres généraux rax, rbx, rcx, rdx, le microprocesseur possède un registre spécial : le registre d'état RFLAGS . Chacun des 64 bits (drapeaux) de ce registre, indique une caractéristique binaire de l'état du processeur. Mais seule une petite partie de ces bits concerne les opérations arithmétiques. Après exécution d'une instruction arithmétique, le bit :

  • ZF (Zero Flag, bit n°6 de RFLAGS) indique si le résultat est nul (ZF=1) ou non nul (ZF=0).

  • SF (Sign Flag, bit n°7 de RFLAGS) indique si le résultat est positif (SF=0) ou négatif (SF=1).

  • PF (Parity Flag, bit n°2 de RFLAGS) indique que le résultat est pair (PF=1) ou impair (PF=0).

  • CF (Carry Flag, bit n°0 de RFLAGS) indique une retenue (CF=1) sur les entiers non signés.

  • OF (Overflow Flag, bit n°11 de RFLAGS), indique un débordement (OF=1) sur les entiers signés.

Lors d'une opération sur n bits, le drapeau CF contiendra le bit numéro n (ou n-1ème bit) du résultat.

Par exemple, sur 8 bits :

  • 0b11111111 + 0b1 = 0b00000000 avec CF = 1

  • 0b00000000 – 0b1 = 0b11111111 avec CF = 1

  • 0b11111110 + 0b1 = 0b11111111 avec CF = 0

On voit donc aisément, que si pour le programmeur, les opérandes sont des entiers non signés, le résultat est valide si et seulement si CF =0 et il est invalide si et seulement si CF = 1.

Exemple

Si pour le programmeur, les opérandes sont des entiers signés, c'est le drapeau OF qui indiquera la validité du résultat. Par exemple, sur 8 bits (non-signés : ℕ8, signés : ℤ8) :

  • 0b11111111 + 0b1 = 0b00000000 avec CF=1 et OF=0 ,

    (255+1) est invalide dans ℕ8, mais (-1+1) est valide dans ℤ8.

  • 0b00000000 – 0b1 = 0b11111111 avec CF=1 mais OF=0,

    (0-1) est invalide dans ℕ8, mais (0-1) est valide dans ℤ8.

  • 0b10000000 + 0b1 = 0b10000001 avec CF=0 et OF=0,

    (128 + 1) est valide dans ℕ8 et (-128 + 1) est valide dans ℤ8.

  • 0b10000000 – 0b1 = 0b01111111 avec CF=0 mais OF =1,

    (128–1) est valide dans ℕ8, mais (-128–1) est invalide dans ℤ8.

  • 0b01111111 + 0b1 = 0b10000000 avec CF=0 mais OF =1,

    (127+1) est valide dans ℕ8, mais (127+1) est invalide dans ℤ8.