Programmation Assembleur/x86/Opérations arithmétiques et logiques

Programmation Assembleur/x86
Modifier ce modèle


Opérandes et résultat

modifier

Les opérations arithmétiques et logiques agissent sur un ou deux opérandes. Il peut s'agir d'un registre, d'un pointeur mémoire ou d'une valeur littérale. Le premier opérande sert également à stocker le résultat, et ne peut donc pas être une valeur littérale.

Exemples :

add ax, bx            ;  Ajouter BX à AX
sub word ptr[bx], ax  ;  Soustraire AX du mot de 16 bits pointé par BX

Opérations arithmétiques

modifier

Les instructions du tableau ci-dessous effectuent une opération arithmétique utilisant deux opérandes représentés ci-dessous par les lettres x et y.

Instruction Opérandes Opération arithmétique
ADD x, y x, y Addition x <- x + y
ADC x, y x, y Addition avec retenue x <- x + y + CF
SUB x, y x, y Soustraction x <- x - y
SBB x, y x, y Soustraction avec retenue x <- x - y - CF

Les instructions de multiplication et division utilisent l'accumulateur (registre AX) comme premier opérande implicitement, seul le deuxième est spécifié. Leurs résultats étant plus grand que le nombre de bits d'entrée, sont stockés dans les registres AX et DX si besoin. Ces instructions se distinguent par l'interprétation des nombres en signés (préfixe I comme Integer) et non signé (pas de préfixe) car contrairement aux autres opérations, les résultats diffèrent complètement selon cette interprétation. Les instructions de la division calculent à la fois le quotient et le reste de la division en une seule opération, et peuvent déclencher une interruption si le second opérande vaut zéro.

Instruction Opérandes Opération arithmétique
MUL y ; y sur 8 bits AL, y Multiplication d'entiers non signés AX <- AL * y
MUL y ; y sur 16 bits AX, y Multiplication d'entiers non signés DX:AX <- AX * y

DX stocke les 16 bits de poids fort du résultat et AX les 16 bits de poids faible.

IMUL y ; y sur 8 bits AL, y Multiplication d'entiers signés AX <- AL * y
IMUL y ; y sur 16 bits AX, y Multiplication d'entiers signés DX:AX <- AX * y

DX stocke les 16 bits de poids fort du résultat et AX les 16 bits de poids faible.

DIV y ; y sur 8 bits AL, y Division d'entiers non signés AX <- AL / y

AL contient le quotient de la division

AH contient le reste de la division

DIV y ; y sur 16 bits AX, y Division d'entiers non signés DX:AX <- AX / y

AX contient le quotient de la division

DX contient le reste de la division

IDIV y ; y sur 8 bits AL, y Division d'entiers signés AX <- AL / y

AL contient le quotient de la division

AH contient le reste de la division

IDIV y ; y sur 16 bits AX, y Division d'entiers signés DX:AX <- AX / y

AX contient le quotient de la division

DX contient le reste de la division

Les indicateurs sont mis à jour selon le résultat.

Les instructions du tableau ci-dessous effectuent une opération arithmétique utilisant un seul opérande :

Instruction Opération arithmétique
NEG x Négation (changement de signe) x <- -x
INC x Incrémentation x <- x + 1
DEC x Décrémentation x <- x - 1

Les indicateurs sont également mis à jour selon le résultat de ces opérations. Cela permet notamment pour les instructions INC et DEC de pouvoir enchaîner avec une instruction de saut conditionnel JZ ou JNZ selon que le résultat est zéro ou différent de zéro afin de réaliser une boucle de répétition pour continuer à l'itération suivante ou sortir de la boucle.

Comparaison et test de bits

modifier

L'instruction CMP compare les deux opérandes numériques. Il s'agit en fait de la même opération que la soustraction de l'instruction SUB excepté que le résultat n'est pas stocké. L'instruction CMP ne fait que mettre à jour les indicateurs. Elle est utilisée juste avant un ou plusieurs sauts conditionnels.

L'instruction TEST teste les bits des deux opérandes numériques. Il s'agit en fait de la même opération que le et logique de l'instruction AND excepté que le résultat n'est pas stocké. L'instruction TEST ne fait que mettre à jour les indicateurs. Elle est utilisée juste avant un ou plusieurs sauts conditionnels.

Opérations logiques

modifier

Les instructions du tableau ci-dessous effectuent une opération logique utilisant deux opérandes représentés ci-dessous par les lettres x et y.

Instruction Opérandes Opération logique
AND x, y x, y Et logique, bit à bit x <- x & y
OR x, y x, y Ou logique, bit à bit x <- x | y
XOR x, y x, y Ou exclusif logique, bit à bit x <- x ^ y

L'instruction NOT du tableau ci-dessous est la seule effectuent une opération logique utilisant un seul opérande :

Instruction Opération logique
NOT x Inversion des bits x <- ~x

Les instructions de décalage et de rotation de bits sont listées ci-dessous. Les premiers modèles de la famille de processeur x86 limitent les possibilités pour le second opérande spécifiant le nombre de positions de décalage :

  • Sur le 8086, le nombre de positions de décalage peut être la valeur constante 1 ou le registre CL ;
  • Le 80186 ajoute la possibilité de spécifier un décalage avec une valeur constante entre 1 et 15 ;
  • Le 80386 ajoute la possibilité de spécifier un décalage avec une valeur constante spécifié sur un octet (0 à 255).
Instruction Opérandes Opération de décalage
SHL x, y ; SHift to the Left

SAL x, y ; Shift Arithmetically to the Left

x, y Décalage des bits de x de y positions vers la gauche x <- x << y
SHR x, y ; SHift to the Right x, y Décalage des bits de x de y positions vers la droite x <- x >>> y
SAR x, y ; Shift Arithmetically to the Right x, y Décalage des bits de x de y positions vers la droite x <- x >> y

Le bit de signe est préservé.

ROL x, y ; ROtate to the Left x, y Rotation des bits de x de y positions vers la gauche. Le bit de poids fort est déplacé dans le bit de poids faible.
ROR x, y ; ROtate to the Right x, y Rotation des bits de x de y positions vers la droite. Le bit de poids faible est déplacé dans le bit de poids fort.
RCL x, y ; Rotate with Carry to the Left x, y Rotation des bits de x de y positions vers la gauche avec le bit de retenue dans la boucle. Le bit de poids fort est déplacé dans CF, dont la valeur d'origine est déplacé dans le bit de poids faible.
RCR x, y ; Rotate with Carry to the Right x, y Rotation des bits de x de y positions vers la droite avec le bit de retenue dans la boucle. Le bit de poids faible est déplacé dans CF, dont la valeur d'origine est déplacé dans le bit de poids fort.

Ajustements des calculs en BCD

modifier

Le Décimal codé binaire (DCB) ou binary coded decimal (BCD) en anglais, est un système de numération où les nombres sont représentés par les chiffres décimaux les composant, chacun codé sur quatre bits. Un octet permet donc de stocker un nombre décimal à 2 chiffres en DCB, de 0x00 à 0x99.

Le 80x86 permet d'effectuer des calculs dans ce mode, en utilisant les opérations arithmétiques normales puis en utilisant des instructions spéciales pour ajuster le résultat. Ces instructions n'ont pas d'opérande explicite et utilisent le registre AX et les indicateurs de retenues CF (Carry Flag) et AF (Auxiliary Carry Flag).

Instruction Ajustement
DAA ; Decimal Adjust for Addition
DAS ; Decimal Adjust for Subtraction
AAA ; Ascii Adjust for Addition
AAS ; Ascii Adjust for Subtraction
AAM ; Ascii Adjust for Multiplication Opérations effectuées :
  • AH <- AL / 10 (interruption Division Overflow si le résultat dépasse 255)
  • AL <- AL % 10
AAD ; Ascii Adjust for Division Opérations effectuées :
  • AL <- AH * 10 + AL
  • AH <- 0

Le codage des instructions AAM et AAD inclut la base 10 comme second octet, et peut donc être changé pour faire l'opération pour une autre base. Certains assembleurs permettent de spécifier une autre base comme opérande de ces instructions. Sinon il est possible de modifier manuellement la base utilisée. Pour l'instruction AAM si la base spécifiée est 0, une interruption Division Overflow est déclenchée.