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

* Programmation Assembleur/x86
* Introduction
* Registres
* Les flags
* Copie entre registres et mémoire
* Les branchements
* La pile
* Les interruptions
* Opérations arithmétiques et logiques
* Interactions avec les périphériques
* Index
* Conclusion
* Modifier ce modèle

## Opérandes et résultat

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 :

## Opérations arithmétiques

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

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

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

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.