Vous êtes sur la page 1sur 26

2 Architecture d’un microprocesseur 16

bits Intel 8086

2.1 Introduction
L’Intel 8086 (également appelé iAPX 86) est un microprocesseur 16 bits fabriqué par
Intel à partir de 1978 (Figure 2.1). C’est le premier processeur de la famille x86, qui est
devenue l’architecture de processeur la plus répandue dans le monde des ordinateurs
personnels, stations de travail et serveurs informatiques. Parmi ses caractéristiques

Fig. 2.1 : photo du processeur Intel 8086 d’origine de 1978 à côté d’un processeur Intel Core
i7-8086K (Core 8ème génération cadencé à 4 GHz en fréquence de base et atteignant 5 GHz
en mode turbo) de 2018 en édition limitée. (Crédit : Intel Corporation)

principales, on peut citer :


Il se présente sous forme d’un boîtier DIP (Dual Inline Package) de 40 broches
(Figure 2.2) alimenté par une alimentation unique de 5V ;
Il possède un bus de donnée de 16 bits ce qui permet d’échanger des mots de 2
octets ;

9
2.2 Architecture Interne du 8086

Il possède un bus d’adresse de 20 bits ce qui permet d’adresser 1 Moctets (220 ) ;


Tous les registres sont de 16 bits, mais pour garder la compatibilité avec les pro-
cesseurs de la précédente génération (8085/8088), certains registres sont décou-
pés en deux et on peut accéder séparément à la partie haute et à la partie basse.

Fig. 2.2 : Brochage du 8086.

2.2 Architecture Interne du 8086


Le 8086 est constitué de deux unités (Figure 2.3) :
L’unité d’interface de bus UIB (ou en anglais, BIU : Bus Interface Unit) le rôle de l’UIB
est d’interagir avec la mémoire et les périphériques d’entrées/sorties pour récu-
pérer et stocker les instructions et les données requises par l’unité d’exécution
(UE).
L’unité d’exécution ( ou en anglais, EU : Execution Unit) est responsable de l’exécu-
tion des instructions des programme qui lui sont transmises par l’UIB et du
traitement requis ;

2.2.1 Unité de Bus et d’Interface (BIU)


Le BIU envoie les adresses, récupère les instructions de la mémoire et lit/écrit les don-
nées de/dans la mémoire ou des ports. Elle gère donc tous les transferts de données et
d’adresses sur les bus pour l’UE.

10
2.2 Architecture Interne du 8086

Fig. 2.3 : Schéma détaillé de l’UE et l’UIB.

La BIU peut stocker jusqu’à 6 octets d’instructions dans un registre FIFO (First In, First
Out ou premier entré, premier sorti) appelé file d’attente. Lorsque l’unité d’exécution
est prête pour l’instruction suivante, la BIU lit alors l’instruction dans sa file d’attente.
La principale raison est d’augmenter la vitesse de traitement du processeur par che-
vauchement des opérations d’extraction d’instructions avec l’exécution. Ce mécanisme
est connu sous le nom de pipeline.

La BIU contient Les registres de segment permettent d’accéder, soit au segment de


programme qui est la zone mémoire des instructions de programme, soit au segment
de données (zone mémoire contenant les données du programme), ou encore au seg-
ment de pile. Elle contient aussi le registre pointeur d’instruction.

Il s’agit de :

CS : Code Segment, registre de segment de code (instructions) ;

DS : Data Segment, registre de segment de données ;

SS : Stack Segment, registre de segment de pile ;

ES : Extra Segment, registre de segment supplémentaire pour les données ;

IP : Instruction Pointer, registre de pointeur d’instruction.

Pour exécuter les instructions dans l’ordre établi par le programme, le microproces-
seur doit savoir à chaque instant l’adresse de la prochaine instruction à exécuter. Le
microprocesseur utilise un registre contenant cette information. Ce registre est appelé

11
2.2 Architecture Interne du 8086

pointeur d’instruction (IP : Instruction Pointer) [Haggège, 2003].

Le registre IP est utilisé comme offset avec le registre segment CS est donc modifié
implicitement par le processeur (instruction suivante, saut à l’adresse indiquée, appel
d’une fonction, interruption ...).

Remarque 2.1 la valeur initiale du pointeur d’instruction est fixée par le constructeur
du microprocesseur. Elle vaut une valeur bien définie à chaque mise sous tension du
microprocesseur ou bien lors d’une remise à zéro (reset).

Pour savoir quel type d’opération doit être exécuté (addition, soustraction, ...), le mi-
croprocesseur lit le premier octet de l’instruction pointée par le pointeur d’instruction
(code opératoire) et le range dans un registre appelé registre d’instruction. Le code
opératoire est décodé par des circuits de décodage contenus dans le microprocesseur.
Des signaux de commande pour l’UAL sont produits en fonction de l’opération de-
mandée qui est alors exécutée [Haggège, 2003].

Remarque 2.2 Pendant que l’instruction est décodée, le pointeur d’instruction est in-
crémenté de façon à pointer vers l’instruction suivante

2.2.2 Gestion de la mémoire par le 8086


Le bus d’adresse de la mémoire réelle est de 20 bits. Or le 8086 n’a pas de registre de
20 bits mais que de 16 bits. Un registre de 16 bits référence 64 Ko de mémoire, soit
216 = 65536. Pour répondre à cette problématique, le 8086 en mode réel combine un
des neuf registres généraux avec l’un des quatre registres de segments pour former une
adresse de 20 bits.

En effet, le 8086 utilise le principe de la segmentation ou pagination ; la mémoire est


divisée en bloc ou segments. Un segment est une zone mémoire de 64 Ko (65 536
octets) qui peut être adressé par un pointeur sur 16 bits ; la taille des registres du 8086.
Chaque segment est complètement définie par son adresse de départ qui doit être un
multiple de 16 ; dans une telle adresse , les 4 bits de poids faible sont à zéro. On peut
donc représenter l’adresse d’un segment avec seulement ses 16 bits de poids fort, les 4
bits de poids faible étant implicitement à 0.

une case mémoire est repérée par le 8086 au moyen de deux valeurs sur 16 bits :

1. l’adresse d’un segment ;

2. un déplacement ou offset (appelé aussi adresse effective) dans ce segment.

Le mécanisme de traduction, illustré par la figure 2.4 , ajoute à ces adresses le contenu

12
2.2 Architecture Interne du 8086

d’un registre de segment multiplié par 16. Cette multiplication correspond à un déca-
lage de 4 bits vers la gauche. L’adresse finale véhiculée par le bus externe est donc sur
20 bits.

Registre Segment (16 bits) 0000

4 bits
Déplacement (offset) (16 bits)
20 16

Additionneur

20

Adresse physique (20 bits)

Fig. 2.4 : Calcul d’adresse physique en segmentation.

La donnée d’un couple (segment,offset) définit une adresse logique, notée sous la forme
segment :offset. L’adresse d’une case mémoire donnée sous la forme d’une quantité sur
20 bits (5 digits hexa) est appelée adresse physique car elle correspond à la valeur en-
voyée réellement sur le bus d’adresses A0-A19.

A un instant donné, le 8086 a accès à 4 segments dont les adresses se trouvent dans
les registres de segment CS, DS, SS et ES. Le segment de code contient les instruc-
tions du programme, le segment de données contient les données manipulées par le
programme, le segment de pile contient la pile de sauvegarde et le segment supplé-
mentaire peut aussi contenir des données.

Exemple 2.1 si le pointeur d’instruction I P = 1A00H et le registre segment de code


C S = 2010H , l’adresse émise (effective ou physique) pour accéder à une instruction
sera :
(2010 ∗ 10)H + 1A00H = 20100H + 1A00H = 21B00H

Remarque 2.3 les segments ne sont pas nécessairement distincts les uns des autres,
ils peuvent se chevaucher ou se recouvrir complètement (Figure 2.5).

2.2.3 Unité d’exécution (UE)


L’UE décode et exécute les instructions. L’UE contient une unité arithmétique et lo-
gique (ALU, pour Arithmetic and Logic Unit en anglais), une unité de contrôle et
un certain nombre de registres. Ces fonctionnalités permettent l’exécution d’instruc-

13
2.2 Architecture Interne du 8086

Fig. 2.5 : Exemple de chevauchement des segments 8086.

tions et d’opérations arithmétiques et logiques. Elle possède neuf registres de 16 bits ;


4 registres d’usage générale AX, BX, CX, DX, 2 registres d’index SI, DI, 2 registres
pointeurs SP, BP et un registre indicateur d’états Flags. Les quatre premiers peuvent
être utilisés comme registre 8 bits (AH, AL, BH, BL, CH, CL, DH, DL).

Registre AX

Le registre AX est appelé accumulateur 16 bits et AL accumulateur 8 bits. Les instruc-


tions E/S (I/O en anglais) (IN ou OUT en assembleur) utilisent toujours AX ou AL
pour l’entrée/la sortie des données 16 ou 8 bits depuis ou vers les ports E/S.

Registre BX

BX est appelé registre de base car il s’agit du seul registre à usage général pouvant être
utilisé comme index pour étendre l’adressage. Il est utilisé pour l’adressage de données
dans une zone mémoire différente de la zone code : en général il contient une adresse
de décalage par rapport à une adresse de référence. (Par exemple, l’adresse de début
d’un tableau). De plus il peut servir pour la conversion d’un code à un autre.

Registre CX

En plus d’être utilisé pour les opérations arithmétiques et logiques, le registre CX est
appelé registre de compteur car certaines instructions telles que SHIFT, ROTATE et
LOOP utilisent CX en tant que compteur.

14
2.2 Architecture Interne du 8086

Registre DX

Le registre DX est appelé registre de données. Certaines opérations d’E / S nécessitent


son utilisation et les opérations de multiplication et de division impliquant des valeurs
élevées supposent l’utilisation conjointe de DX et de AX.

Registres pointeurs de pile (SP) et pointeur de base (BP)

Les deux sont utilisés pour accéder aux données du segment de pile. SP et le pointeur
de Pile ; utilisé pour l’accès à la pile. Il représente le décalage (offset) relatif à SS (registre
de segment qui indique l’adresse de début de la pile). Le contenu du SP est automati-
quement mis à jour (incrémenté/décrémenté) lors de l’exécution des opérations POP
et PUSH (voir le fonctionnement de la pile).

Le registre BP est utilisé par les instructions utilisant le mode d’adressage basé et
contient l’adresse de décalage dans le segment de pile actuel.

Les registres d’index

Les deux registres d’index SI (Source Index) ou index de source et DI (Destination


Index) ou index de destination sont utilisés dans l’adressage indexé. Il sont générale-
ment utilisés par les instructions qui traitent des chaînes de caractères ou les tableaux
afin de distinguer les adresses source et de destination.

Le registre d’état (Flags)

Le 8086 a neuf drapeaux (indicateur d’état) de 1 bit (Figure 2.6). Sur les neuf, six re-
flètent des états du processeur après chaque instruction exécutée (retenue (addition
ou soustraction), dépassement, comparaison, autoriser les interruptions, …) et trois
sont des drapeaux de contrôle. Les bits de contrôle peuvent être définis ou réinitialisés
par le programmeur.

O D I T S Z A P C
D15 D0

Fig. 2.6 : Registre indicateur d’état - Flags

O : Overflow Flag Drapeau de dépassement de capacité. Cet indicateur est défini à 1


si un dépassement de capacité arithmétique se produit ; c’est-à-dire si le résultat
d’une opération signée ne peut pas tenir dans le registre de destination.

15
2.2 Architecture Interne du 8086

D : Direction Flag Indicateur de direction. Il est utilisé par les instructions de mani-
pulation de chaîne. Si ce bit est égal à « 0 », la chaîne est traitée en commençant
par l’adresse la plus basse jusqu’à l’adresse la plus élevée, c’est-à-dire en mode
d’incrémentation automatique. sinon, la chaîne est traitée de l’adresse la plus
élevée à l’adresse la plus basse, c’est-à-dire en mode de décrémentation automa-
tique.

I : Interrupt flag Si cet indicateur est défini à 1, les interruptions masquables sont re-
connues par la CPU, sinon, elles sont ignorées.

T : Trap flag Si cet indicateur est défini à 1, le processeur entre en mode d’exécution
pas à pas. En d’autres termes, une interruption d’arrêt est générée après l’exé-
cution de chaque instruction. Le processeur exécute l’instruction en cours et le
contrôle est transféré au programme générant l’interruption.

S : Sign flag Cet indicateur est défini lorsque le résultat d’un calcul est négatif. Pour
les calculs signés, le drapeau de signe est égal au MSB (le bit le plus significatif
ou Most Significant Bit en anglais) du résultat.

Z : Zero flag Cet indicateur est défini à 1 lorsque le résultat du calcul est/ou que la
comparaison effectuée par l’instruction précédente est égale à zéro. ç-à-d. 1 pour
un résultat nul et 0 pour un résultat non nul.

A : Auxiliary Carry indique une retenue sur les 4 bits (digit) de poids faible. Par exemple
quand la somme des 2 digits de poids faible dépasse F (15). Le cas le plus cou-
rant d’utilisation de cet indicateur est les opérations sur les nombre BCD (Binary
Coded Decimal).

P : Parity flag Cet indicateur est défini à 1 si l’octet inférieur du résultat contient un
nombre pair de 1, sinon il est défini à 0.

C : Carry flag cet indicateur est défini à 1 lorsque :

deux nombres non signés sont additionnés et le résultat dépasse la ”capa-


cité” du registre de destination. Ex : on veut ajouter deux nombres sur 8
bits et sauvegarder le résultat dans un registre de 8 bits. 255 + 9 = 264, le ré-
sultat ne peut pas tenir dans un registre de 8 bits. Donc, la valeur ”8” sera
sauvegardée ici (264 % 256 = 8) et le drapeau CF sera défini.

on soustrait deux nombres non signés. On soustrait le plus grand du plus


petit. Ex : 1-2 = 255 comme résultat et le drapeau des FC sera défini à 1.

16
2.3 Programmation du 8086

2.3 Programmation du 8086

2.3.1 Introduction
Chaque microprocesseur reconnaît un ensemble d’instructions appelé jeu d’instruc-
tions (Instruction Set) fixé par le constructeur.

Remarque 2.4 Une instruction réalise une action simple sur le microprocesseur, comme
”récupérer une nombre en mémoire”, ”additionner deux nombres et placer le résultat
en mémoire”.

Une instruction est composée de deux champs :

le code opération, qui indique au processeur quelle instruction réaliser ;

le champ opérandes qui contient les données, ou les références aux données en
mémoire (adresses).

Une instruction est définie par son code opération, valeur numérique binaire difficile
à manipuler par l’être humain. On utilise donc une notation symbolique pour repré-
senter les instructions : les mnémoniques.

L’assembleur aura pour rôle de convertir le fichier source contenant les instructions ;
en mnémoniques en actions sur les registres et mémoire. Le fichier exécutable produit
contient les codes binaires de chacune des instructions, compréhensible uniquement
par le microprocesseur associé. L’assembleur est donc qu’une traduction d’un fichier
source éditer en langage de haut niveau vers un langage binaire (de bas niveau) .

Exemple 2.2 Soit l’instruction de transfert suivante :


mov [1100H], 15H

mov est le mnémonique de l’instruction de transfert et [1100H] et 15H sont les opérandes.

Les instructions et leurs opérandes (paramètres) sont stockées en mémoire principale.


La taille totale d’une instruction (nombre de bits nécessaires pour la représenter en
mémoire) dépend du type d’instruction et aussi du type d’opérande.

Intel x86 utilise un codage à largeur variable. Ainsi, le processeur doit avoir une logique
interne qui met à jour le pointeur d’instruction (IP) dans le cadre de son processus de
décodage d’instruction. Il récupère l’instruction, la décode et incrémente le pointeur
d’instruction de la taille réelle de l’instruction décodée.

17
2.3 Programmation du 8086

2.3.2 Les modes d’adressage du 8086


Une instruction est toujours codée sur un nombre entier d’octets, afin de faciliter
son décodage par le processeur. Les façons de désigner les opérandes constituent les
«  modes d’adressage  ». Selon la manière dont les opérandes (les données) sont spéci-
fiés, c’est à dire selon le mode d’adressage de la donnée, une instruction sera codée par
1, 2, 3 ou 4 octets.

Le microprocesseur 8086 possède plusieurs modes d’adressage.

Adressage registre (R)


L’opération se fait sur un ou 2 registres.
mov AX,BX ;transfert entre registres
inc CL ; incrémenter CL (CL=CL+1)

Adressage Immédiat (IM)


Ce type d’instruction met en jeu un registre et une valeur (qu’il s’agisse d’une affec-
tation, une addition, une soustraction ou bien même une comparaison), la taille de
l’opérande dépendra donc du type de registre mis en jeu (1 octet pour un registre 8
bits, 2 pour un registre de 16 bits).
mov AX,56 ;charger registre AX par la valeur 56 décimal
add AX,16H ;addition du contenu de AX avec la valeur 16 en hexa
inc CL ;incrémenter CL (CL=CL+1)

Adressage Direct (D)


Un des deux opérandes se trouve en mémoire. L’adresse de la case mémoire ou plus
précisément son Offset est précisé directement dans l’instruction. L’adresse Rseg:Off
doit être placée entre [], si le segment n’est pas précisé, DS est pris par défaut.
mov AX, [243] ;Copier le contenu de la mémoire d’adresse DS:243 dans AX
mov [123], AX ;Copier le contenu de AX dan la mémoire d’adresse DS:123
mov AX, [SS:243] ;Copier le contenu de la mémoire SS:243 dans AX

18
2.3 Programmation du 8086

Adressage indirect (IR)


Un des deux opérandes se trouve en mémoire. L’offset de l’adresse n’est pas précisé
directement dans l’instruction, il se trouve dans l’un des 4 registres d’offset BX, BP, SI
ou DI et c’est le registre qui sera précisé dans l’instruction : [Rseg:Roff].
mov AX, [BX] ; Charger AX par le contenu de la mémoire d’adresse DS:BX
mov AX, [BP] ; Charger AX par le contenu de la mémoire d’adresse SS:BP
mov AX, [SI] ; Charger AX par le contenu de la mémoire d’adresse DS:SI
mov AX, [DI] ; Charger AX par le contenu de la mémoire d’adresse DS:DI
mov AX, [ES:BP] ; Charger AX par le contenu de la mémoire d’adresse ES:BP

Adressage basé (BA)


l’offset est contenu dans un registre de base BX ou BP. On peut préciser un déplacement
qui sera ajouté au contenu de Roff pour déterminer l’offset

Exemples

mov AL,[BX] : transfère la donnée dont l’offset est contenu dans le registre de base BX
vers le registre AL. Le segment associé par défaut au registre BX est le segment de
données : on dit que l’adressage est basé sur DS ;

mov AL,[BP] : le segment par défaut associé au registre de base BP est le segment de pile.
Dans ce cas, l’adressage est basé sur SS ; AL <– [SS :BP]

mov AX, [ES:BP] : Charger AX par le contenu de la mémoire d’adresse ES :BP.

mov AX, [BP+5] : Charger AX par le contenu de la mémoire d’adresse SS :BX+5

Adressage indexé (X)


Ce mode est semblable à l’adressage basé, sauf que l’offset est contenu dans un registre
d’index SI ou DI, associés par défaut au segment de données DS.

Exemples

: charge le registre AL avec le contenu de la case mémoire dont l’offset est


mov AL,[SI]
contenu dans SI ; AL <– [DS :SI].

mov [DI],BX : charge les cases mémoire d’offset DI et DI+1 avec le contenu du registre
BX.

19
2.4 Jeux d’instruction du 8086

mov [SI+100H],AX : charge les cases mémoire d’offset SI+100H et SI+101H avec le conte-
nu du registre AX.

qui peut aussi s’écrire


mov [SI][100H],AX

ou encore
mov 100H[SI],AX

adressage basé et indexé (BXI)


L’offset est obtenu en faisant la somme d’un registre de base, d’un registre d’index et
éventuellement d’une valeur constante.

Exemple 2.3 Adressage indexé

mov AX,[BX+SI] ; AX est chargé par la mémoire d’adresse DS:BX+SI


mov AX,[BX+DI+5] ; AX est chargé par la mémoire d’adresse DS:BX+DI+5
mov AX,[BP+SI-8] ; AX est chargé par la mémoire d’adresse SS:BP+SI-8
mov AX,[BP+DI] ; AX est chargé par la mémoire d’adresse SS:BP+DI

Ce mode d’adressage permet l’adressage de structures de données complexes : ma-


trices, enregistrements, ...

Exemple 2.4 Adressage Matrices


mov BX,10
mov SI,15
mov byte ptr matrice[BX][SI],12H

Dans cet exemple, BX et SI jouent respectivement le rôle d’indices de ligne et de co-


lonne dans la matrice.

2.4 Jeux d’instruction du 8086


Les instructions d’un processeur dépendent fortement du processeur utilisé. La liste
de toute les instructions qu’un processeur peut exécuter s’appelle son jeu d’instruc-
tions. Celui-ci définit les instructions supportées, ainsi que la manière dont elles sont
encodées en mémoire.

20
2.4 Jeux d’instruction du 8086

2.4.1 Les instructions de transfert


Elles permettent de déplacer des données d’une source vers une destination :
mov dst,src ;Copie l’opérande src dans l’opérande dst
mov reg./mem , reg./mem./imed ; {reg : regsitre, mem : mémoire, imed : imédiat (valeur
numérique)} ;

Exemple 2.5 Transfert


mov AX, BX ; copie le contenu du registre BX dans le registre AX. Adressage par registre
mov AL, 12H ; charge le registre AL avec la valeur 12H. Adressage immédiat.
mov BL,[1200H]; copie le contenu de la case mémoire d’adresse effective (offset) 1200H vers le
registre BL. Adressage direct.
mov byte ptr [1200H] , 23H; copier la valeur 23H dans la case mémoire d’adresse DS:1200H
(byte = 1 octet)
mov word ptr [1200H] , 50H; copier la valeur 0050H dans la case mémoire d’adresse DS:1200H
(word = 2 octet); le prmier octet (poid faible; 50H) à l’adresse DS:1200H et le deuxième
(poid fort; 00H) à l’adresse DS:1201H.

2.4.2 Les instructions arithmétiques


Les instructions arithmétiques de base sont l’addition, la soustraction, la multiplica-
tion et la division qui incluent diverses variantes. Les opérations peuvent s’effectuer
sur des nombres de 8 bits ou de 16 bits signés ou non signés. Les nombres signés sont
représentés en complément à 2. Des instructions d’ajustement décimal permette de
faire des calculs en décimal (BCD).

Addition & soustraction


add dst,src ;Additionne src et dst; résultat dans dst, dst <– des + src
add reg./mem , reg./mem./imed ;(8 bits ou 16 bits)
sub dst,src ;Soustrait src et dst; résultat dans dst. dst <– des - src
sub reg./mem , reg./mem./imed ;(8 bits ou 16 bits)

Exemple 2.6 Addition


add AH,[1100H] ; ajoute le contenu de la case mémoire d’offset 1100H à l’accumulateur AH
(adressage direct) ;
add AH,[BX] ; ajoute le contenu de la case mémoire pointée par BX à l’accumulateur AH
(adressage basé);

21
2.4 Jeux d’instruction du 8086

add byte ptr [1200H],05H ; ajoute la valeur 05H au contenu de la case mémoire d’offset
1200H (adressage immédiat).

Addition & soustraction avec retenue


adc dst,src ;Additionne src et dst et le bit de retenue (CF); le résultat dans dst, dst <– des +
src + CF
sbb dst,src ;soustrait src et dst et le bit de retenue (CF); le résultat dans dst, dst <– des - src -
CF

Incrémentation & décrémentation


inc/dec reg./mem. ;(8 bit ou 16bit) –> ajouter/soustraire 1 à l’opérande

Exemple 2.7 Incrémentation/Décrémentation


inc AL ; AL <– AL+1
dec BX ; AL <– AL-1
inc BYTE [BP] ; Incrémente l’octet à l’adresse [BP], adressage basé sur DS
inc WORD [BX] ; Incrémente le mot à l’adresse [BX], adressage basé sur DS

multiplication & division

Cette instruction effectue la multiplication du contenu de AL par un opérande sur 1


octet ou du contenu de AX par un opérande sur 2 octets. Le résultat est placé dans AX
si les données à multiplier sont sur 1 octet (résultat sur 16 bits), dans (DX,AX) si elles
sont sur 2 octets (résultat sur 32 bits).

multiplication non signée Multiplication non signé en binaire normale.


mul reg8/mem8 ; (multiplication 8 bit : accumulateur – AL) AX <– AL * (reg8/mem8)
mul reg16/mem16 ; (multiplication 16 bit : accumulateur – AX) (DX,AX) <– AX * (reg16/mem16)

multiplication signée Même opération que MUL mais prend en compte le signe.
imul reg8/mem8 ; (multiplication signée 8 bit : accumulateur – AL) AX <– AL * (reg8/mem8)
imul reg16/mem16 ; (multiplication signée 16 bit : accumulateur – AX) (DX,AX) <– AX *
(reg16/mem16)

Exemple 2.8 Multiplication


mul BL ; AL * BL → AX
mul CX ; AX * CX → DX:AX

22
2.4 Jeux d’instruction du 8086

mul byte [BX] ; AL * (octet pointé par BX) → AX


mul word [BX] ; AX * (word pointé par BX) → DX :AX

Exercice

Soit à multiplier le nombre (8EH) par (5H) ; on utilisera l’instruction mul et imul :
mov AL, 8EH
mov BL,05H
mul BL ; AL et BL sont considérés comme des nombres non signés (AL=142, BL=5) AX <– AL * BL.
(AX = 142*5 = 710 = 02C6H)
mov AL, 8EH ; recharger AL par la valeur 8EH
imul BL ; AL et BL sont considérés comme des nombres signés, et de ce fait, AL contient
maintenant la valeur (8EH=10001101b = -114; bit de signe (MSB) égale à 1) AX <– AL * BL.
(AX = -114*5 = -570 = FDC6H)

Division non signée Division non signé en binaire normale.


div reg8/mem8 ; (divison 8 bit) AX/reg8 ou AX/mem8 AL <– quotient, AH <– Reste)
div reg16/mem16 ; (divison 16 bit) (DX,AX)/reg16 ou (DX,AX)/mem16 AX <– quotient, DX <–
Reste)

Division signée Même opération que div mais prend en compte le signe.
idiv reg8/mem8 ; (divison 8 bit) AX/reg8 ou AX/mem8 AL <– quotient, AH <– Reste)
idiv reg16/mem16 ; (divison 16 bit) (DX,AX)/reg16 ou (DX,AX)/mem16 AX <– quotient, DX <–
Reste)

Instructions divers

neg reg./mem complément à deux de l’opérande

AAA : ajustement ASCII après addition

AAS : ajustement ASCII après soustraction

AAM : Ajuster après la multiplication

AAD : Ajuster après la division

DAA : ajustement décimal après addition

DAS : ajustement décimal après soustraction

23
2.4 Jeux d’instruction du 8086

2.4.3 Les instructions logiques, de décalage et de comparaison


2.4.3.1 Les instructions logiques

opérations logique niveau bit


AND/OR/XOR reg./mem, reg./mem./imed ; ET, OU et OU exclusif
NOT reg/mem ;

Exemple 2.9 Opérations logiques


AND AL, AH ; ET logique bit à bit du contenu de AL et AH; le résultat est dans AL
XOR [BX], CL ; OU exclusif entre le contenu de la mémoire DS:BX et le contenu de CL; le résultat
est suvegardé dans la case mémoire

Chacune de ces instructions a de très nombreuses applications, il serait impossible de


toutes les énumérer. En voici quelques-unes :

Masquage Il est possible de masquer, c’est-à-dire mettre à zéro tous les bits qui ne
nous intéressent pas dans un nombre. Pour cela il faut créer une valeur masque : un
nombre dont les bits de poids qui nous intéressent sont à 1, les autres à 0. Il suffit alors
de faire un AND entre le nombre à masquer et le masque pour ne conserver que les bits
auxquels on s’intéresse.
Forcer un bit à 0 on utilise la propriété de l’opérateur AND ; à savoir : x AND 0 = 0 .

x x x x x x x x
Exemple : AND 1 1 1 0 1 1 1 0
x x x 0 x x x 0

Forcer un bit à 1 on utilise la propriétés de l’opérateur OR ; à savoir : x OR 1 = 1 .

x x x x x x x x
Exemple : OR 0 0 0 1 0 0 0 0
x x x 1 x x x x

2.4.3.2 Les instructions de décalage

Ces instructions déplacent d’un certain nombre de positions les bits d’un mot vers la
gauche ou vers la droite. Dans les décalages, les bits qui sont déplacés sont remplacés
par des zéros. Il y a les décalages logiques (opérations non signées) et les décalages
arithmétiques (opérations signées) (Figure 2.7).

24
2.4 Jeux d’instruction du 8086

avant
avant 1 1 0 0 1 0 1 1

1 1 0 0 1 0 1 1 après CF
après CF 1 1 1 0 0 1 0 1 → 1
0 → 0 1 1 0 0 1 0 1 → 1

(a) Logique (b) Arithmétique

Fig. 2.7 : Décalage (à droite) Arithmétique et logique

shl mem./reg, imed/CL ; décalage logique à gauche de imed fois ou le nombre est donné
par le registre CL
shr mem./reg, imed/CL ; décalage logique à droite de imed fois ou le nombre est donné par
le registre CL

sal mem./reg, imed/CL ; décalage arithmétique à gauche de imed fois ou le nombre est
donné par le registre CL
sar mem./reg, imed/CL ; décalage arithmétique à droite de imed fois ou le nombre est donné
par le registre CL

2.4.3.3 Les instructions de rotation

Ces instruction font pivoter les bits mentionnés vers le côté gauche ou droite un à un.
Le bit sortant est également stocké dans le Carry Flag (CF) (Figure 2.9).
rol mem./reg, imed/CL ; rotation de l’opérande 1 à gauche. Le nombre de rotations est défini
par l’opérande 2 (imed ou CL).
ror mem./reg, imed/CL ; rotation de l’opérande 1 à droite. Le nombre de rotations est défini
par l’opérande 2 (imed ou CL).

CF Données Données CF

(a) Gauche (b) Droite

Fig. 2.8 : Rotation à gauche et à droite

Exemple 2.10 Rotation


mov AL,0x1C ; AL = 00011100b
rol AL, 1 ; AL = 00111000b, CF=0.

Les instructions suivantes décalent l’opérande vers la gauche/droite en passant par l’in-
dicateur de retenue CF.

25
2.4 Jeux d’instruction du 8086

rcl mem./reg, imed/CL ; (Rotate Through CF Left ) Rotation à gauche à travers le Carry
(retenue)
rcr mem./reg, imed/CL ; (Rotate Through CF Right ) Rotation à droite à travers le Carry
(retenue)

CF Données Données CF

(a) Gauche (b) Droite

Fig. 2.9 : Rotation à gauche et à droite à travers le Carry flag

Exemple 2.11 Rotations avec bit de retenu


stc ; set carry (CF=1).
mov AL,0x1C ; AL = 00011100b
rcl AL, 1 ; AL = 00111001b, CF=0.

stc ; set carry (CF=1).


mov AL,0x1C ; AL = 00011100b
rcr AL, 1 ; AL = 10001110b, CF=0.

2.4.3.4 Les instructions de comparaison


cmp reg./mem, reg./mem./imed ;Compare (soustrait) les opérandes source et destination (le
prmeier) et positionne les drapeaux en fonction du résultat. L’opérande de destination
n’est pas modifié.

Cette instruction est généralement utilisée avec les instructions de saut conditionnels
(voir plus loin).
test reg./mem, reg./mem./imed ;test les bits (opération AND) entre tous les bits et positionne
les drapeaux en fonction du résultat (ZF, SF, PF). L’opérande de destination n’est pas
modifié.

Exemple 2.12 Test et comparaison


cmp AL,BH ; if (AL > BH) CF=ZF=SF=0; if (AL = BH) CF=SF=0 et ZF=1; if (AL < BH) CF=SF=1 et ZF=0;

mov AL, 00000101b


test AL, 1 ; ZF = 0.
test AL, 10b ; ZF = 1.
ret

26
2.4 Jeux d’instruction du 8086

2.4.3.5 Les instructions de branchement

Les instructions de branchement (ou saut) permettent de modifier l’ordre d’exécution


des instructions du programme en fonction de certaines conditions. Il existe 3 types
de saut :

saut inconditionnel ;

sauts conditionnels ;

appel de sous-programmes.

Instruction de saut inconditionnel Cette instruction effectue un saut (jump) vers


l’étiquette (label) spécifiée.
jmp etq1 ; Provoque un saut sans condition à la ligne portant l’étiquette etq1.

Remarque 2.5 Une étiquette est un symbole qui représente l’adresse mémoire d’une
instruction ou d’une donnée. L’adresse peut être relative au compteur programme (IP),
relative au registre ou absolue. Exemple : etq1:

Instruction d’appel de sous-programme Cette instruction transfère le contrôle à la


procédure (sous-programme) mentionnée, l’adresse de retour (IP) est poussée à la pile.
call proc./label./4-byte address ; saut au sous-programme nommé ”proc”, à l’étiquette
”label”, à une adresse de la forme 1234h:5678h (dans ce cas la valeur de CS est aussi
sauvegardée dans la pile)

Exemple 2.13 Appel de procédure


ORG 100h
CALL p1
ADD AX, 1
RET ; fin de programme (retour à l’OS).
p1 PROC ; procédure déclaration.
MOV AX, 1234h
RET ; retour au programme appelant.
p1 ENDP

Instruction de saut conditionnel Un saut conditionnel n’est exécuté que si une cer-
taine condition est satisfaite, sinon l’exécution se poursuit séquentiellement à l’instruc-
tion suivante.

27
2.5 La pile (stack)

La condition du saut porte sur l’état de l’un (ou plusieurs) des indicateurs d’état (flags)
du microprocesseur :

Pour les valeurs non signées


JB/JNAE ;below/ not above or equal CF = 1
JAE/JNB ;above or equal/not below CF=0
JBE/JNA ;below or equal CF=1 et ZF=1
JA/JNBE ;above/not below or equal
JE/JZ ;equal/zero ZF=1
JNE/JNZ ;not equal/not zero ZF=0

Pour les valeurs signées


JL/JNGE ;less than/not greater than SF <> OF
JGE/JNL ;greater or equal/not less than SF=OF
JLE/JNG ;less or equal/not greater than ZF=1 ou SF<>OF
JG/JNLE ;greater than/not less or equal ZF=0 ou SF=OF
JP/JPE ;Parity even (paire) PF=1
JNP/JPO ;Parity odd (impaire) PF=0
JS ;signé SF=1
JNS ;non signé SF=0
JC ;retenue CF=1
JNC ;pas de retenue CF=0
JO ;overflow OF=1
JNO ;pas d’overflow OF=0

2.5 La pile (stack)


La pile est une zone de mémoire permettant de stocker et retrouver rapidement des
valeurs suivant le mode LIFO (Last In First Out : dernier entré, premier sorti).

Une pile fonctionne à la manière d’une pile d’objets réels :

Il est possible d’ajouter une valeur au sommet de la pile (empiler) ;

Il est possible de retirer la valeur située au sommet de la pile (dépiler).

Cette opération est automatiquement effectuée lors de l’exécution des instructions


d’appel et de retour (call , ret ). Il est également possible de le faire manuellement avec
les instructions push et pop.

Le sommet de la pile est situé à décalage SP dans le segment de pile (indiqué par ailleurs

28
2.6 Les procédures (sous-programmes)

par le registre CS), donc PUSH AX, par exemple, est équivalent à SUB SP, 2 (il faut rappe-
ler que la pile croît vers le bas) suivi de MOV [SS:SP], AX (sauf que [SS :SP] n’est pas une
forme valide de référence de mémoire) (Figure 2.10).

SS=2000H
20000
20001
20002

croissantes
AX=17FE

Adresses
CX=AB03

Taille de la pile
2FFF9
2FFFA 03H CL SP=FFFA
2FFFB ABH CH PUSH CX
2FFFC FEH AL SP=FFFC
2FFFD 17H AH PUSH AX
SP=FFFE

Fig. 2.10 : Principe de fonctionnement de la pile du processeur 8086.

push reg16./mem16 ; (reg16 comprend aussi les registres de segments) sauvegarder la valeur
sur un mot (2 octets) et décrémente le pointeur de pile de 2 SP<–SP-2

Remarque 2.6 Il est important de comprendre qu’on ne peut dépiler que le mot qui
se trouve au sommet de la pile. Le premier mot empilé est le dernier qui sera dépilé.
La pile doit être manipulée avec une extrême précaution. Un dépilage injustifié fait
planter la machine presque systématiquement.

2.6 Les procédures (sous-programmes)


En langage assembleur, on appelle procédure un sous-programme qui permet d’ef-
fectuer un ensemble d’instructions par simple appel de la procédure. Cette notion de
sous-programme est généralement appelée fonction dans d’autres langages. Les fonc-
tions et les procédures permettent d’exécuter dans plusieurs parties du programme
une série d’instructions, cela permet une simplicité du code et donc une taille de pro-
gramme minimale.
On déclare une procédure (nommée ici Calcul) dans le segment d’instruction comme
suit :
Calcul Proc [near/far] ; procédure nommée Calcul
... ; instructions
RET ; dernière instruction

29
2.6 Les procédures (sous-programmes)

Calcul ENDP ;fin de la procédure

La déclaration de la procédure commence par une étiquette (qui représente le nom de


la fonction ici Calcul) précédant le mot clé PROC marquant le début de la procédure,
suivi de near ou far (qui signale que la procédure est située dans le même segment
que le programme appelant ou dans un segment différent) et RET désignant la dernière
instruction, et enfin le mot clé ENDP qui annonce la fin de la procédure.

2.6.1 Appel de la procédure


L’instruction CALL permet l’appel d’une procédure. Elle est suivie soit d’une adresse 16
bits, désignant la position du début de la procédure, ou bien du nom de la procédure
(celui de l’étiquette qui précède le mot clé PROC) ; exemple : call fct (Figure 2.11).

Fig. 2.11 : Exemple d’un appel de fonction en assembleur.

2.6.2 Retour au programme appelant


Une question peut être posée ; Comment l’unité de traitement arrive-t-elle à retourner
au programme principal à la fin de la procédure ?

En fait, au moment de l’appel de la fonction, l’adresse de l’instruction suivante est sau-


vegardée dans la pile :

appel proche (near) : sauvegarde de IP

appel lointain (far) : sauvegarde de CS puis de IP

A la fin de la procédure, l’UT récupère les valeurs sauvegardées pour retourner au


programme principal

30
2.6 Les procédures (sous-programmes)

2.6.3 Le passage de paramètres


Une procédure effectue généralement des actions sur des données qu’on lui fournit
(appelées paramètres ou arguments), toutefois dans la déclaration de la procédure il
n’y a pas de paramètres (dans des langages évolués (C, C++, …) on place généralement
les noms des variables paramètres entre des parenthèses, séparés par des virgules). Il
existe toutefois deux façons de passer des paramètres à une procédure en assembleur :

Passage par registres on stocke les valeurs dans les registres utilisés dans la procé-
dure. Toutefois, et à cause du nombre limité de registres, on ne peut pas passer
autant de paramètres que l’on désire. néanmoins, c’est la méthode la plus simple.

Passage par la pile on stocke les valeurs dans la pile avant d’appeler la procédure, puis
on lit le contenu de la pile dans la procédure. La technique consiste à empiler les
paramètres dans la pile, ensuite il suffit d’accéder dans la procédure aux données
à travers un registre pointeur (BP) qui permet de lire des valeurs dans la pile sans
les dépiler, ni modifier le pointeur de sommet de pile (SP).

Exemple : passage par la pile

Soit le programme suivant calculant la moyenne de deux nombres en utilisant une


procédure Moyenne.
; programme principal
;...
PUSH N1
PUSH N2
Call Moyenne
POP Res
;...

La procédure Moyenne :
Moyenne PROC
PUSH BP
MOV BP, SP
PUSH AX ; sauvegarde de AX (solution propre)
MOV AX, [BP+4] ; transfert de N2
ADD AX, [BP+6] ; ajouter N1
SHR AX, 1 ; diviser par 2
MOV [BP+6], AX ; le résultat à la place de N1
POP AX ; restaurer le registre AX d’avant la procédure

31
2.6 Les procédures (sous-programmes)

POP BP ; restaurer le registre BP d’avant la procédure


RET 2 ; retour au programme principale (on récupère la valeur de IP dans la pile) et en plus
efface la case suivante de la pile (N2); SP pointe maintenant la valeur du résultat
Moyenne ENDP

Les paramètres d’entrée sont empilés avant l ’appel de la procédure ;


Les paramètres de sortie sont dépilés par le programme principal.
l’évolution du contenu de la pile est schématisé dans la figure 2.12.
T0 T1=push N1 T2=push N2

SP
N2
SP
SP N1 N1

(a) t = 0 (b) t = 1 (c) t = 2


T3=CALL Moyenne T4=push BP

SP
BP (ancien)
SP
IP de retour IP de retour
N2 N2
N1 N1

(d) t = 3 (e) t = 4

Fig. 2.12 : Evolution du contenu de la pile lors de l’exécution du programme de l’exemple

Le rôle du registre BP est de pointer le sommet de la pile au moment de l’appel de la


procédure. Ainsi, il est possible d’accéder aux données de la pile sans les instructions
push et pop. Dans cet exemple : [ BP+4] correspond à N2 et [ BP+6] à N1.

32
2.6 Les procédures (sous-programmes)

T5=push َAX
T6=mov [BP+6], AX T7= pop AX
SP
SP
AX AX
BP (ancien) SP
BP (ancien) BP (ancien)
IP de retour IP de retour IP de retour
N2 N2 N2
N1 (N1+N2)/2 (N1+N2)/2

(a) t = 5 (b) t = 6 (c) t = 7


T7= pop BP T8= ret 2 T9= pop Res

SP
IP de retour
N2
SP
(N1+N2)/2 (N1+N2)/2
SP
(d) t = 8 (e) t = 9 (f) t = 10

Fig. 2.13 : Évolution du contenu de la pile lors de l’exécution du programme de l’exemple -


Partie 2 -

33
2.6 Les procédures (sous-programmes)

34

Vous aimerez peut-être aussi