Le Microprocesseur 8086 8088
Le Microprocesseur 8086 8088
Le Microprocesseur 8086 8088
I ) Introduction :
Le processeur 8086 d'Intel est à la base des processeurs Pentium actuels. Les processeurs
successifs (de PC) se sont en effet construits petit à
petit en ajoutant à chaque processeurs des instructions et des
fonctionnalités supplémentaires, mais en conservant à chaque fois les
spécificités du processeur précédent. C'est cette façon d'adapter les processeurs à chaque
étape qui permet qu'un ancien programme écrit pour un 8086 fonctionne toujours sur un
nouvel ordinateur équipé d'un Pentium IV.
Le 8086 (développé en 1978) est le premier microprocesseur de type x86.Il est équipé d'un
bus de données de 16 bits et un bus d'adresses de 20 bits et fonctionne à des fréquences
diverses selon plusieurs variantes: 5, 8 ou 10 MHz.
III ) Architecture interne du 8086 :
Il existe deux unités internes distinctes: l'UE (Unité d'Exécution) et l'UIB (Unité d'Interfaçage
avec le Bus). Le rôle de l'UIB est de récupérer et stocker les informations à traiter, et d'établir
les transmissions avec les bus du système. L'UE exécute les instructions qui lui sont
transmises par l'UIB. L'image ci-dessous résume les notions présentées ici. Le
microprocesseur pris comme exemple est le 8086/8088. Les processeurs actuels de la famille
x86 traitent les informations de la même façon.
Nous pouvons à présent examiner plus en détail le traitement des instructions par 'UE et
l'UIB. Avec le microprocesseur 8085, le traitement des instructions se passait comme suit:
Remarque :
Les registres généraux peuvent être utilisés dans toutes les opérations
arithmétiques et logiques que le programmeur insère dans le code assembleur. Un
registre complet présente une grandeur de 16 bits. Comme le montre la figure 2, chaque
registre est en réalité divisé en deux registres distincts de 8 bits. De cette façon, nous pouvons
utiliser une partie du registre si nous désirons y stocker une valeur n'excédant pas 8 bits. Si, au
contraire, la valeur que nous désirons y ranger excède 8 bits, nous utiliserons le registre
complet, c'est à dire 16 bits. Nous verrons plus loin qu'il est possible de manipuler facilement
les registres généraux.
Le programmeur dispose de 8 registres internes de 16 bits qu'on peut diviser en deux groupes
comme le montre la figure 2 :
(AH,AL,BH,BL,CH,CL,DH et DL )
- groupe de pointeur et indexe : formé de 4 registres de 16 bits (SI, DI, SP, BP) et font
généralement référence à un emplacement en mémoire.
Groupe de données :
Registre AX : (Accumulateur)
Toutes les opérations de transferts de données avec les entrées-sorties ainsi que le traitement
des chaînes de caractères se font dans ce registre, de même les opérations arithmétiques et
logiques.
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.
Lors de l'exécution d'une boucle on a souvent recours à un compteur de boucles pour compter
le nombre d'itérations, le registre CX a été fait pour servir comme compteur lors des
instructions de boucle.
Remarque :
Le registre CL sert en tant que compteur pour les opérations de décalage et de rotation,
dans ce cas il va compter le nombre de décalages (rotation) de bits à droite ou à gauche.
Registre DX :
Un cas particulier de pointeur est le pointeur de pile (Stack Pointer : SP). Ce registre permet
de pointer la pile pour stocker des données ou des adresses selon le principe du "Dernier Entré
Premier Sorti" ou "LIFO"
Il permet de pointer la mémoire il forme en général un décalage (un offset) par rapport à une
base fixe (le registre DS), il sert aussi pour les instructions de chaîne de caractères, en effet il
pointe sur le caractère source
Il permet aussi de pointer la mémoire il presente un décalage par rapport à une base fixe (DS
ou ES), il sert aussi pour les instructions de chaîne de caractères, il pointe alors sur la
destination
Ils pointent sur la zone pile (une zone mémoire qui stocke l'information avec le principe filo :
voir plus loin), ils presentent un décalage par rapport à la base (le registre SS). Pour le registre
BP il a un rôle proche de celui de BX, mais il est généralement utilisé avec le segment de pile.
Il pointe sur le segment qui contient les codes des instructions du programme en cours.
Remarque :
Si la taille du programme dépasse les 65535 octets alors on peut diviser le code sur plusieurs
segments (chacun ne dépasse pas les 65535 octets) et pour basculer d'une partie à une autre du
programme il suffit de changer la valeur du registre CS et de cette manière on résout le
problème des programmes qui ont une taille supérieure à 65535 octets.
Le registre SS pointe sur la pile : la pile est une zone mémoire ou on peut sauvegarder les
registres ou les adresses ou les données pour les récupérer après l'exécution d'un sous
programme ou l'exécution d'un programme d'interruption, en général il est conseillée de ne
pas changer le contenu de ce registre car on risque de perdre des informations très
importantes (exemple les passages d'arguments entre le programme principal et le sous
programme)
Les drapeaux sont des indicateurs qui annoncent une condition particulière suite à une
opération arithmétique ou logique.
Remarque :
CF (Carry Flag) :
CF = 1 s'il y a une retenue après l'addition ou la soustraction du bit de poids fort des
opérandes. Exemples (sur 8 bits pour simplifier) :
PF (Parity Flag) :
Parité : si le résultat de l'opération contient un nombre pair de 1 cet indicateur est mis à 1,
sinon zéro.
AF (Auxiliary Carry) :
Demie retenue : Ce bit est égal à 1 si on a une retenue du quarter de poids faible dans le
quarter de poids plus fort.
ZF (Zero Flag) :
Zéro : Cet indicateur est mis à 1 quand le résultat d'une opération est égal à zéro.
Lorsque l'on vient d'effectuer une soustraction (ou
une comparaison), ZF=1 indique que les deux opérandes étaient égaux. Sinon, ZF est
positionné à 0.
SF (Sign Flag) :
SF est positionné à 1 si le bit de poids fort du résultat d'une addition ou soustraction est 1 ;
sinon SF=0. SF est utile lorsque l'on manipule des entiers signés, car le bit de poids fort donne
alors le signe du résultat. Exemples (sur 8 bits) :
OF (Overflow Flag) :
DF (Direction Flag) :
IF(Interrupt Flag) :
TF (Trap Flag) :
Remarque :
V ) Gestion de la mémoire :
V-1 ) Introduction :
L'espace mémoire adressable (1 méga = 2 20 bits du bus d'adresse ) du 8086/8088 est divisé
en quatre segment logiques allant jusqu'à 64 KOctets chacun . L'accès à ces espaces est direct
et simultané, or Le compteur de programme est de 16 bits donc la possibilité d'adressage est
de 2 16 = 64 Ko (Ce qui ne couvre pas la totalité de la mémoire), alors on utilise deux
registres pour indiquer une adresse au processeur, Chaque segment débute
à l'endroit spécifié par le registre segment. Le déplacement (offset) à l'intérieur de
chaque segment se fait par un registre de décalage qui permet de trouver une information à
l'intérieur du segment. Exemple la paire de registre CS:IP : pointe sur le code d'une
instruction (CS registre segment et IP Déplacement)
Remarque :
On appellera segment de mémoire une zone mémoire adressable avec une valeur fixée du
segment (les 16 bits de poids fort). Un segment a donc une taille maximale de 64 Ko.
Le pointeur de pile (en combinaison avec le segment de pile SS) pointe vers le dessus de la
pile (TOS : top of stack) en mémoire. Une pile est un ensemble de données placées en
mémoire de manière à ce que seulement la donnée du "dessus" soit disponible à un instant
donné. Pour aller chercher la donnée sous celle du dessus par exemple, on doit d'abord
enlever celle du dessus. Le rôle du pointeur de pile (et de la pile vers laquelle il pointe) est le
suivant. Quand un processeur exécute une instruction, il est possible qu'il soit interrompu par
une "Interruption" (c'est-à-dire un appel au processeur qui est prioritaire aux instructions du
programme qu'il traite). Il doit alors arrêter de s'occuper de l'instruction qu'il traite
présentement pour s'occuper
de l'interruption. Quand l'interruption sera traitée, il retournera à l'instruction qu'il
traitait quand il a été interrompu. Mais pour cela, il doit se rappeler de cette instruction ainsi
que de l'état de certains registres au moment où il traitait l'instruction. Donc pour ne pas les
perdre, il les placera temporairement dans une pile (à l'intérieur de la mémoire RAM par
exemple) et pourra les récupérer une fois l'interruption traitée. Le pointeur de pile (SP) donne
donc l'adresse en mémoire de cette pile temporaire.
Les piles offrent un nouveau moyen d'accéder à des données en mémoire principale, qui
est très utilisé pour stocker temporairement des valeurs.
Le schéma suivant montre comment une valeur est stocker dans la pile (pushed) et comment
elle est récupérée (poped) :
Le microprocesseur 8086 est processeur 16 bits (bus de données de 16 bits), ce qui donne la
possibilité à ce microprocesseur d'accéder en même temps à deux cases mémoires de 8 bits.
En effet pour le 8086 la mémoire est organisée en deux Banks (un bank pair et un bank impair
chacun de 512 Koctet) comme le montre la figure suivante :
Les bits D0..D7 sont appelé partie base alors que les bits D8..D15 sont appelé partie haute. Le
8086 peut charger un octet (8 bits) ou un mot (16 bits) ou un double mot (32 bits) de la
mémoire, en effet pour l'octet il suffit de donner l'adresse de ce dernier pour être chargé dans
la CPU, pour le mot il suffit de donner l'adresse le 8086 cherche l'octet du poids faible à
l'adresse donnée et l'octet du poids le plus fort à l'adresse qui suit , mais un problème apparaît
lorsque on veut accéder à une case mémoire impaire tel que 135 par exemple , en effet
:
La figure suivante montre comment les cases sont rangées dans les deux banks :
Si on veut accéder par exemple à l'octet (8 bits) d'une adresse paire celle ci
sera directement transmise sur les lignes D0...D7 mais si on veut accéder à une
adresse impaire tel que 135 par exemple, donc il faut aussi que la donnée
serait charger sur les lignes D0.. D7, or en réalité et en regardant l'organisation
de la mémoire e par la figure précédente on constate que la donnée sera
transmise sur les lignes D8..D15 (adresse impaire) ce qui va obliger le
microprocesseur de
changer cette octet du poids haut au poids faible d'une manière
automatique.
Remarque :
Pour sélectionner les banks pair et impair le microprocesseur utilise deux signaux (BHE et A0
: le premier bit du bus d'adresse) comme le montre la figure suivante :
Pour sélectionner le bank pair A0=0