Instructions 8086
Instructions 8086
Instructions 8086
Chapitre 3
Dans ce chapitre, nous présentons une par une les instructions du 8086.
La première ligne indique le nom des bits intéressants de FLAGS. La deuxième ligne (vide ici) indique
l’effet de l’instruction sur un bit en particulier. On note :
* le bit est modifié en fonction du résultat de l’exécution de l’instruction
? le bit a une valeur indéfinie après l’exécution de l’instruction
1 le bit est mis à 1
0 le bit est mis à 0
Une case vide indique que l’indicateur n’est pas modifié par l’instruction.
20 CHAPITRE 3. LES INSTRUCTIONS DU 8086
O D I T S Z A P C
* * * * * *
L’instruction ADD effectue l’addition du contenu du registre source au registre destination, sans report de
retenue, soit ;
alors le registre AX contient la valeur 1bh, le bit C est positionné à la valeur 1, la retenue auxiliaire A est
mise à 0.
Si nous considérons les deux instructions suivantes ;
alors le registre AX contient la valeur 43h, le bit C est mis à 0, la retenue auxiliaire A est mise à 1.
O D I T S Z A P C
* * * * * *
L’instruction SUB effectue la soustraction du contenu du registre source au registre destination, sans
report de retenue, soit ;
le registre AX contient ensuite la valeur 21h. Les bits Z, S et C du registre FLAGS sont mis à 0 car le résultat
n’est pas nul, son signe est positif et aucune retenue n’est générée.
Si nous considérons les deux instructions suivantes ;
le registre AX contient ensuite la valeur cdh. Le bit Z est mis à zéro. Les bits C, A et S sont mis à 1.
IMUL
MUL Les multiplications en assembleur
IMUL registre/variable
O D I T S Z A P C
* ? ? ? ? *
mov al, 4
mov ah, 25
imul ah
À l’issue de l’exécution de ces 3 instructions, le registre AH contient la valeur 100, produit de 4 par 25.
Pour bien comprendre la différence entre les instructions imul et mul, regardons les exemples suivants :
À l’issue de l’exécution de ces 3 instructions, ax contient la valeur be8c et dx la valeur f, soit la valeur
hexadécimale fbe8c, c’est-à-dire 1031820, le produit de 435 par 2372. Les deux données étant positives, le
résultat est le même que l’on utilise l’instruction imul ou l’instruction mul.
Considérons maintenant la séquence d’instructions :
mov bx, -435
mov ax, 2372
imul bx
À l’issue de leur exécution, ax contient la valeur 4174 et dx contient la valeur fff0, soit la valeur -1031820.
Si l’on remplace imul par mul, le résultat n’a pas de sens.
IDIV
DIV Les divisions en assembleur
IDIV registre/variable
O D I T S Z A P C
? ? ? ? ? ?
Les deux instructions DIV et IDIV réalisent les opérations de division et de calcul de reste. DIV l’effectue
sur des données non signées, IDIV sur des données signées.
Dans tous les cas, le dividende est implicite. Le diviseur est fourni en opérande. Le résultat se compose
du quotient et du reste de la division. Le reste est toujours inférieur au diviseur. On a le choix entre :
– la division d’une donnée 16 bits stockée dans AX par une donnée 8 bits qui fournit un quotient dans AL
et un reste dans AH sur 8 bits.
– la division d’une donnée 32 bits stockée dans la paire de registres DX (poids fort) et AX (poids faible)
par une donnée 16 bits qui fournit un quotient dans AX et un reste dans DX sur 16 bits.
DEC décrémentation
DEC registre/variable
O D I T S Z A P C
* * * * *
DEC soustrait 1 au contenu de l’opérande, sans modifier l’indicateur de retenue.
Soient les instructions assembleur suivantes ;
mov al, 01h
dec al
AL contient ensuite la valeur 00. Le bit Z est mis à 1, les bits O, P, A et S mis à 0.
INC incrémentation
INC registre/variable
O D I T S Z A P C
* * * * *
INC ajoute 1 au contenu de l’opérande, sans modifier l’indicateur de retenue.
Soient les instructions assembleur suivantes ;
mov al, 3fh
inc al
AL contient ensuite la valeur 40h. Le bit Z est mis à 0 (le résultat de l’incrémentation n’est pas nul), l’indi-
cateur de retenue auxiliaire bit A est mis à 1 (passage de retenue entre les bits 3 et 4 lors de l’incrémentation),
les bits bit O et bit S mis à 0 (pas de débordement de capacité, le signe du résultat est positif).
NEG registre/variable
O D I T S Z A P C
* * * * * *
NEG transforme la valeur d’un registre ou d’un opérande mémoire en son complément à deux. Ainsi, après
exécution des instructions ;
mov ax, 35
neg ax
le registre AX contient la valeur -35.
24 CHAPITRE 3. LES INSTRUCTIONS DU 8086
AND et-logique
O D I T S Z A P C
0 * * ? * 0
AND réalise un et-logique bit à bit entre l’opérande source et l’opérande destination. Le résultat est rangé
dans l’opérande destination.
Considérons les deux lignes suivantes :
OR ou-logique
OR registre/variable, registre
OR regisre, registre/variable
OR registre/variable, constante
O D I T S Z A P C
0 * * ? * 0
OR réalise un ou-logique bit à bit entre l’opérande source et l’opérande destination. Le résultat est rangé
dans l’opérande destination.
Considérons les deux lignes suivantes :
XOR ou-exclusif
3.1. LES INSTRUCTIONS ARITHMÉTIQUES ET LOGIQUES 25
O D I T S Z A P C
0 * * ? * 0
XOR réalise un ou-exclusif bit à bit entre l’opérande source et l’opérande destination. Le résultat est rangé
dans l’opérande destination.
Considérons les deux lignes suivantes :
NOT registre/variable
O D I T S Z A P C
NOT transforme la valeur d’un registre ou d’un opérande mémoire en son complément logique bit à bit.
Considérons les deux lignes suivantes :
RCL
ROL
RCR
ROR Les rotations en assembleur
26 CHAPITRE 3. LES INSTRUCTIONS DU 8086
Opérande retenue
- -
6 6 6 6 6 6 6
a.SAR
Opérande retenue
¾
Opérande retenue 6 6 6 6 6 6 6 6
-
d.ROL
6 6 6 6 6 6 6
b.SHR
Opérande retenue
¾
retenue Opérande 6 6 6 6 6 6 6 6
¾ ¾ 0
e.RCL
6 6 6 6 6 6 6
c.SHL (équivalent à SAL)
Les rotations sont des opérations logiques binaires fréquemment utilisées. Elles considèrent un opérande
(octet ou mot) comme un tore dont elles décalent les bits. Lors du décalage, un bit déborde d’un côté, à
gauche ou à droite, selon le sens de la rotation. Selon le cas, quelques détails diffèrent ;
RCL le bit de poids fort est mis dans l’indicateur de retenue C, la valeur de cet indicateur étant préalablement
mise dans le bit de poids faible (cf. figure 3.1.e)
ROL le bit de poids fort est mis dans l’indicateur de retenue C et dans le bit de poids faible de l’opérande.
L’ancienne valeur de l’indicateur de retenue n’est pas utilisée (cf. figure 3.1.d)
æ
Les opérandes des instructions RCL, RCR, ROL et ROR. étant les mêmes, nous n’en présentons qu’une,
l’instruction RCL.
RCL registre/variable, 1
RCL registre/variable, CL
O D I T S Z A P C
* *
RCL effectue une rotation à gauche de l’opérande destination indiqué, 1 ou CL fois, en prenant en compte
le contenu de l’indicateur de retenue. Le bit de poids fort de l’opérande destination est mis dans la retenue.
Le contenu de la retenue est mis dans le bit de poids faible de l’opérande destination.
RCR effectue une rotation à droite de l’opérande destination indiqué, 1 ou CL fois, en prenant en compte
le contenu de l’indicateur de retenue. Le bit de poids faible de l’opérande destination est mis dans la retenue.
Le contenu de la retenue est mis dans le bit de poids fort de l’opérande destination.
3.1. LES INSTRUCTIONS ARITHMÉTIQUES ET LOGIQUES 27
ROL effectue une rotation à gauche de l’opérande destination indiqué, 1 ou CL fois, sans prendre en
compte le contenu de l’indicateur de retenue. Le bit de poids fort est mis dans l’indicateur de retenue lors
de la rotation ainsi que dans le bit de poids faible de l’opérande.
ROR effectue une rotation à droite de l’opérande destination indiqué, 1 ou CL fois, sans prendre en compte
le contenu de l’indicateur de retenue. Le bit de poids faible est mis dans l’indicateur de retenue lors de la
rotation ainsi que dans le bit de poids fort de l’opérande.
où xxx est une instruction de rotation. Selon le choix de cette instruction, nous obtenons les résultats
suivants ;
xxx rcl rcr rol ror
al b0h 85h b0h 85h
C 0 1 0 1
SAL
SHL
SAR
SHR Les décalages en assembleur
Une opération de décalage consiste simplement à décaler tous les bits d’une donnée. Contrairement aux
rotations qui considèrent une donnée (un octet ou un mot) comme un tore, un décalage considère la donnée
comme une file ; ainsi, le bit qui (( déborde )) de la retenue est perdu.
Les opérandes des instructions SAL, SAR, SHL et SHR étant les mêmes, nous ne présentons qu’une seule
instruction, SAL.
SAL registre/variable, 1
SAL registre/variable, CL
O D I T S Z A P C
* * * ? * *
SAL et SHL sont des synonymes et peuvent être utilisées l’une pour l’autre indifféremment. SAL effectue
un décalage vers la gauche, sauvegardant le bit de poids fort dans l’indicateur de retenue et mettant un 0
dans le bit de poids faible (cf. figure 3.1.c).
SHR effectue un décalage vers la droite. Le bit de poids faible est mis dans la retenue. Un 0 est mis dans
le bit de poids fort de la donnée (cf. figure 3.1.b).
SAR effectue un décalage vers la droite, sauvegardant le bit de poids faible dans l’indicateur de retenue.
Par ailleurs (et c’est là toute la différence avec l’instruction précédente), le bit de poids fort est conservé (cf.
figure 3.1.a). Le bit de poids fort de la donnée initiale est donc dupliqué.
Le registre AL contient ensuite la valeur b0h. En effet, 16h s’écrit 00010110 en binaire. Si on décale cette
valeur de trois positions vers la gauche, on obtient 10110000, soit b0h Le bit C est mis à 0.
Considérons les deux lignes suivantes :
mov al, 36h
mov cl, 3
sar al, cl
Le registre AL contient ensuite la valeur 05h. Le bit C est mis à 1.
La différence entre les instructions SAR et SAL n’apparait que si le bit de poids fort de la donnée vaut
1. Le tableau suivant donne, pour deux valeurs de la donnée (mise dans le registre AL), l’effet des différents
décalages.
al f0 70
sar al, 1 f8 38
shr al, 1 78 38
Il faut noter que pour un nombre, un décalage d’une position vers la gauche correspond à une multipli-
cation de ce nombre par 2 et qu’un décalage d’une position vers la droite correspond à une division entière
par 2. En généralisant, un décalage de l positions vers la gauche correspond à une multiplication par 2l et
un décalage de l positions vers la droite correspond à une division par 2l . Il faut bien noter, et c’est ce qui
justifie l’existence des deux instructions sar et shr et leur subtile différence, que sar effectue une division
sur un nombre en représentation signée tandis que shr effectue une division sur un nombre en représentation
non signée.
Bien entendu, les opérations de décalage étant connues comme des opérations logiques binaires et non des
opérations arithmétiques, on prendra garde à l’interprétation des indicateurs de débordement ou de retenue
que l’on fera à l’issue d’une instruction de décalage.
Ces instructions réalisent des transferts de données entre 2 adresses mémoire, 2 registres, ou entre un
registre et la mémoire. Ceci correspond donc à l’affectation des langages de haut niveau A:= B.
O D I T S Z A P C
Par exemple, supposons que nous voulions transférer le contenu du registre DS dans le registre ES. Nous
pouvons l’écrire sous la forme suivante :
mov ax, ds
mov es, ax
Remarquons qu’au cours de cette opération, la valeur du registre AX a été perdue lors de l’exécution
de la première instruction. Ceci peut poser un problème qui pourra être résolu en utilisant les techniques
présentées à la section 4.3.2.
O D I T S Z A P C
Ctte instruction charge l’offset de la donnée référencée dans le deuxième opérande qui est, en général,
une donnée déclarée dans le segment de données.
O D I T S Z A P C
L’instruction XCHG échange le contenu de deux emplacements mémoire ou registres. Supposons que le
registre AX contienne la valeur 20 et le registre DX la valeur 10, l’exécution de l’instruction :
xchg ax, dx
– effectue une rupture de séquence (un saut) vers un endroit précis dans le code où l’exécution se poursuit
normalement.
Nous présentons l’instruction CMP, les instructions de sauts conditionnels et inconditionnels puis présen-
tons sur des exemples le codage des tests.
CMP comparaison
C’est l’instruction la plus utilisée pour positionner les indicateurs avant d’effectuer une instruction de
saut conditionnel.
O D I T S Z A P C
* * * * * *
CMP permet de comparer deux valeurs. Pour cela CMP soustrait le second opérande du premier, sans
cependant modifier l’opérande destination, mais en positionnant les indicateurs en fonction du résultat.
Ainsi, si le résultat de la soustraction est nul, donc l’indicateur Z a été positionné à 1, cela signifie que les
deux valeurs comparées sont égales. En utilisant des raisonnements du même genre, on peut savoir si les
deux valeurs sont différentes, ordonnées strictement ou non.
mov al, 23
cmp al, 34
le registre AL n’est pas modifié par l’exécution de l’instruction CMP et contient toujours la valeur affectée
auparavant 23. L’indicateur de retenue C est positionné à 1, ce qui indique que le deuxième opérande de
l’instruction CMP est supérieur à la valeur du premier opérande. L’indicateur de zéro Z valant 0, cela indique
que les deux données sont différentes (sinon, la soustraction d’un nombre à lui-même donne 0, donc le bit Z
est positionné à 1). Le bit de signe S est également mis à 1 car 29 − 34 est un nombre négatif.
Toutes les instructions de saut conditionnel prennent le même type d’opérande (attention, bien distinguer
la valeur zéro 0 du bit O du registre d’état) :
O D I T S Z A P C
Toutes ces instructions fonctionnent selon le schéma suivant. Quand la condition est vraie, un saut est
effectué à l’instruction située à l’étiquette spécifiée en opérande.
Notons que les tests d’ordre (inférieur, supérieur, ...) se comprennent de la manière suivante. Supposons
que nous comparions deux données par une instruction CMP et que nous exécutions ensuite une instruction
JG, c’est-à-dire (( saut si plus grand )). Il y aura alors saut si la valeur du deuxième opérande de l’instruction
CMP est supérieur à la valeur du premier opérande.
L’étiquette référencée dans l’instruction de saut conditionnel ne doit pas se trouver trop loin de l’instruc-
tion de saut. Sinon, une erreur d’assemblage est déclenchée et le message :
Relative jump out of range by xxx bytes
est affiché. Pour remédier à cette erreur, il faut procéder de la manière suivante. Supposons que l’instruc-
tion :
je etiquette
provoque l’erreur en question. Il faut transformer cette instruction dans la séquence d’instructions :
jne nouvelle-etiquette
jmp etiquette
nouvelle-etiquette:
C’est-à-dire :
JMP étiquette
O D I T S Z A P C
L’instruction JMP effectue un saut inconditionnel à l’étiquette spécifiée. Contrairement à un saut condi-
tionnel, le saut est toujours effectué, le registre FLAGS n’intervenant en rien dans cette opération.
Si la valeur de l’expression condition est vraie, les instructions composant la partie action-alors sont
exécutées. Sinon, les instructions de la partie action-sinon sont exécutées.
En assembleur, ce type de construction est réalisé à l’aide du squelette de programme suivant :
calcul de la condition
Jcc SINONn
action-alors
...
JMP FSIn
SINONn:
action-sinon
...
FSIn:
...
où Jcc dénote l’une des instructions de saut conditionnel vues plus haut.
Nous notons les points suivants :
– en fonction de ce positionnement, un saut conditionnel est réalisé par l’instruction Jcc (où cc représente
la condition à tester – voir les différentes possibilités dans la section traitant des instructions de saut
conditionnel) vers la partie sinon du test. Si la condition est vérifiée, aucun saut n’est réalisé et le
programme poursuit son exécution en séquence avec les instructions de la partie action-alors
– une fois les instructions de la partie alors exécutées, un saut doit être réalisé (instruction JMP FSIn)
pour atteindre la fin de la structure de test afin de ne pas également exécuter la partie sinon
– une étiquette (SINONn) est déclarée indiquant le début de la partie action-sinon où le branchement
conditionnel doit être exécuté pour déclencher l’exécution des instructions de la partie sinon du test
– une fois la partie sinon exécutée, on continue en séquence avec les instructions situées après le test
(c’est-à-dire, après l’étiquette FSIn)