Cours Microprocesseur
Cours Microprocesseur
Cours Microprocesseur
Paix-Travail-Patrie . Peace-Work-Fatherland
MINISTERE DE L’ENSEIGNEMENT SUPERIEUR MINISTRY OF HIGHER EDUCATION
INSTITUT UNIVERSITAIRE ROYAL DE BABOUTCHA ROYAL UNIVERSITY INSTITUTE OF
SCIENCE-SAGESSE-SUCCES BABOUTCHA NINTCHEU
NINTCHEU
Autorisation N° 15-03800
/L/MINESUP/SG/DDES/ESUP/SDA/MM du 21 avril 2015
B.P. 285Bafang Situé à Ndokovi Tél: 651 86 51 40/ 664-627-136 / 699-590-924Email: iurb2016@gmail.com
Option : Mécatronique
Enseignant :
L'apparition des microprocesseurs date du début des années 1970. A cette époque, deux
événements favorables sont apparus :
le concept de "LSI (Large Scale Integration)" permettant d'intégrer plusieurs milliers de portes
sur un même substrat.
l'arrivée à maturité de la technologie MOS caractérisée par sa faible consommation.
La conjugaison de ces événements a permis de regrouper une unité centrale d'ordinateur dans un
seul circuit intégré appelé "microprocesseur". Depuis, une multitude de composants de ce type sont
apparus au sein de familles provenant essentiellement de grands constructeurs américains :
Intel, Motorola, Advanced Micro Devices (AMD), Texas Instruments,... et japonais : NEC,
Mitsubishi,...
Grâce aux progrès de l'intégration, l'augmentation des performances a porté sur :
la vitesse de fonctionnement.
la largeur des mots traités (8, 16, 32, 64 bits).
le nombre et la complexité des opérations réalisables.
L'intégration a également permis de rassembler le microprocesseur et les éléments associés
(mémoire, organes d'entrée-sortie,...) au sein d'un seul circuit appelé "microcontrôleur". Ce type de
composant s'est répandu dans
un très grand nombre de domaines (télécommunications, télévision, électroménager, hifi...).
Comme son nom l'indique, cette unité peut exécuter deux types d'opérations.
- Opérations arithmétiques
- Opérations logiques
Ces opérations sont effectuées bit à bit sur les bits de même poids de deux mots, tel que ET, OU,
NOT OU EXCLUSIF, de même les opérations de rotation et de décalage (arithmétique et logique)
Elle reçoit ses opérandes (les octets qu'elle manipule) du bus de données. Celles-ci peuvent
provenir de registres ou de la mémoire. A la fin d'une opération, l'UAL peut aller modifier certains bits
du registre d'état
(FLAG). Par exemple, dans le cas du débordement d'une addition (que le résultat de l'addition est
trop grand pour entrer dans un registre), l'UAL va mettre le bit de débordement du FLAG à 1.
Il s'agit donc essentiellement d'un automate exécutant les différentes séquences propres à chaque
instruction. Cet automate peut être réalisé de plusieurs façons (câbler ou micro-programmer et dans
les deux cas le jeu d'instructions est fixe). La plupart des unités de traitement sont micro-
programmées et donc à jeux d'instructions fixes.
Une interruption est signalée au processeur par un signal électrique sur une borne spéciale. Lors de
la réception de ce signal, le processeur (traite) l'interruption dès la fin de l'instruction qu'il était en
train d'exécuter. Le traitement de l'interruption consiste soit :
- à l'ignorer et passer normalement à l'instruction suivante : c'est
possible uniquement pour certaines interruptions, nommées interruptions masquables. Il est
en effet parfois nécessaire de pouvoir ignorer les interruptions pendant un certain temps, pour
effectuer des traitements très urgents par exemple. Lorsque le traitement est terminé, le
processeur démasque les interruptions et les prend alors en compte.
- à exécuter un traitant d'interruption (interrupt handler). Un traitant
d'interruption est un programme qui est appelé automatiquement lorsqu'une interruption survient.
L'adresse de début du traitant est donnée par la table des vecteurs d'interruptions (voir chapitre
interruption).
Remarque :
Parfois le microprocesseur est sollicité par plusieurs interruptions en même temps, pour répondre à
ces appels un ordre de priorité est souvent pris en compte pour leurs traitements.
Les interruptions augmentent considérablement l'efficacité du processeur.
Les interruptions sont de deux types :
* Interruption matérielle.
* Interruption logicielle.
III-2 /L'écriture en mémoire (WRITE):
Pour écrire une donnée dans la mémoire le microprocesseur doit placer l'adresse de la donnée
sur le bus d'adresses (son emplacement dans la mémoire) puis il place la donnée sur le bus de
données et enfin génère le signal WRITE (ordre d'écriture dans la mémoire).
Pour lire une donnée de la mémoire le microprocesseur doit connaître son emplacement, en effet il
dépose son adresse sur le bus d'adresses puis génère le signal READ (il demande une opération de
lecture de la mémoire) alors la donnée sera acheminée vers le microprocesseur à travers le bus de
données. La donnée sera stockée dans un registre dans le microprocesseur.
Remarque :
Si la donnée est un code opératoire d'une instruction alors elle sera logée dans le registre
d'instructions sinon elle sera logée dans un registre de données (en général l'accumulateur)
III-4 ) Wait Stat (temps d'attente pour la synchronisation) :
Le Wait Stat n'est qu'un temps d'attente qu'il faut donner à certains périphériques pour terminer leurs
opérations (Notamment la mémoire), en effet en général dans la plupart des systèmes à base de
6
microprocesseur on trouve toujours des circuits intermédiaires entre la CPU et la mémoire
comme le montre la figure suivante :
Ces circuits entraînent toujours des temps de retard supplémentaires ce qui oblige le
microprocesseur à utiliser des Wait Stat (temps de retard)
pour synchroniser les transferts entre la mémoire et la CPU .la figure précédente montre que
le microprocesseur perd environ 10 ns pour avoir l'information à cause du décodage et la
bufférisation du bus.
Remarque :
Parfois le microprocesseur utilise plus qu'un seul Wait Stat pour
synchroniser avec ces périphériques (tout dépend du temps que le périphérique demande pour
achever son fonctionnement)
III- 5 /Communication avec les entrées/sorties :
Il peut s'agir d'un flux d'informations de l'extérieur vers l'ordinateur (Acquisition via le clavier, une
connexion réseau, un disque dur, etc...), ou d'un flux de l'ordinateur vers l'extérieur (écran, réseau,
disque, etc...).
Les données échangées entre un périphérique et le processeur transitent par l'interface (ou
contrôleur) associé à ce périphérique .L'interface possède de la mémoire tampon pour stocker les
données échangées (suivant le type
d'interface, cette mémoire tampon fait de 1 seul octet à quelques Méga-
octets).L'interface stocke aussi des informations pour gérer la communication avec le
périphérique :
- des informations de commande, pour définir le mode de fonctionnement de
l'interface: sens de transfert (entrée ou sortie), mode de transfert des
données (par scrutation ou interruption), etc. Ces informations de commandes sont
communiquées à l'interface lors de la phase d'initialisation de celle-ci, avant le début du transfert.
- des informations d'état, qui mémorisent la manière dont le transfert c'est effectué
(erreur de transmission, réception d'informations, etc). Ces informations sont destinées au
processeur.
Lors de l'exécution des instructions d'entrées/sorties, le processeur met à 1 sa borne IO/M et
présente l'adresse E/S sur le bus d'adresse. Le signal IO/M indique aux circuits de décodage
7
d'adresses qu'il ne s'agit pas d'une adress
en mémoire principale, mais de l'adresse d'une interface d'entrées/sorties.
Remarque :
La communication entre le microprocesseur et les interfaces d' entrées/sorties peut être série
(sur un seul fil bit par bit) ou parallèle (sur plusieurs fils)
III -6 ) Accès direct à la mémoire (DMA)
Lorsqu'un transfert en mémoire est nécessaire de la mémoire RAM à un port d'E/S, la CPU lit le
premier octet en mémoire et le charge dans l'un
des registres du microprocesseur. La CPU écrit ensuite l'octet rangé précédemment sur le port
d'E/S approprié.
Il en résulte que le microprocesseur effectue des opérations de lecture et d'écriture répétées. Ainsi
un certain temps est perdu entre le traitement de chaque octet. Pour remédier à ce problème, une
procédure est mise au point
pour l'accès direct à la mémoire (Direct Memory Acess), qui permet de transférer des données
de la mémoire RAM au port d'E/S sans passer par le microprocesseur. Pour cela, un contrôleur
DMA, qui reprend le rôle de la CPU, c'est à dire qu'il gère les transferts de la RAM aux ports d'E/S.
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.
II ) Architecture externe du 8086 :
Le 8086 est un circuit intégré de forme DIL de 40 pattes comme le montre la figure suivante :
8
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:
-Extraction des instructions par l'UIB
- Exécution des instructions
- Extraction des nouvelles instructions
Remarque :
La file d'attente d'instructions contient des informations qui attendent
d'être traitées par l'UE. La file d'attente est parfois appelée capacité de traitement. Le
microprocesseur 8086 est capable de mémoriser jusqu'à six octets. Les microprocesseurs actuels
sont bien entendu équipés d'une file d'attente plus rapide et plus large, c'est à dire capable
d'emmagasiner plus d'informations.
IV ) Les registres du 8086/8088 :
IV-1 ) Introduction :
Le jeu de registres contient l'ensemble des registres du microprocesseur. Un registre
est une petite partie de mémoire intégrée au
microprocesseur, dans le but de recevoir des informations spécifiques, notamment des
adresses et des données stockées durant l'exécution d'un programme. Il existe plusieurs types de
registres. Certains d'entre eux sont affectés à des opérations d'ordre général et sont accessibles au
programmeur à tout moment. Nous disons alors qu'il s'agit de registres généraux. D'autres registres
ont des rôles bien plus spécifiques et ne peuvent pas servir à un usage non spécialisé.
IV-2 ) Les registres généraux :
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 :
- groupe de données : formé par 4 registres de 16 bits (AX,BX,CX,et
DX) chaque registre peut être divisé en deux registres de 8 bits
(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 :
Le registre d'état FLAG sert à contenir l'état de certaines opérations effectuées par le processeur.
Par exemple, quand le résultat d'une opération est trop grand pour être contenu dans le registre cible
(celui qui doit contenir le résultat de l'opération), un bit spécifique du registre d'état (le bit OF) est mis
à 1 pour indiquer le débordement.
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) :
13
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) :
Masque d'interruption : pour masquer les interruptions venant de l'extérieur
ce bit est mis à 0, dans le cas contraire le microprocesseur reconnaît l'interruption de
l'extérieur.
TF (Trap Flag) :
Piége : pour que le microprocesseur exécute le programme pas à pas du.
Remarque :
Les instructions de branchements conditionnels utilisent les indicateurs (drapeaux), qui sont
des bits spéciaux positionnés par l'UAL après certaines opérations. Chaque indicateur est manipulé
individuellement par des instructions spécifiques.
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
14
segment. Exemple la paire de registre CS:IP : pointe sur le code d'une instruction (CS registre
segment et IP Déplacement)
Le schéma de la figure suivante illustre la formation d'une adresse 20 bits à partir du segment et du
déplacement sur 16 bits :
Remarque :
15
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) :
16
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 :
17
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.
Si on veut accéder à un mot : si l'adresse est paire on n'aura pas de problème le pois faible sera
chargé sur les lignes D0...D7 et le pois fort sera chargé sur les lignes D8...D15 donc l'accès à la
mémoire se fait avec un seul cycle .mais si on veut accéder à un mot logé dans une case impaire tel
que 135 par exemple alors il nous faut deux cycles pour charger la donnée en effet l'organisation de
la mémoire nous donne la disposition suivante :
18
Donc le microprocesseur doit accéder à la mémoire en deux temps le premier pour chercher l'octet
135 et le deuxième pour chercher l'octet haut à partir de l'adresse 136.de plus il doit permuter ces
deux octet pour avoir le poids faible sur les lignes D0...D7 et le poids fort sur les lignes D8...D15.
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 :
I ) Introduction :
Lorsque l'on doit lire ou écrire un programme en langage machine, il est difficile d'utiliser la notation
hexadécimale. On écrit les programmes à
l'aide des instructions en mnémonique comme MOV, ADD, etc. Les
concepteurs de processeurs, comme Intel, fournissent toujours une documentation avec les
codes des instructions de leurs processeurs, et les symboles correspondantes.
L'assembleur est un utilitaire qui n'est pas interactif, (contrairement à l'utilitaire comme debug : voir
plus loin dans le cours). Le programme que l'on désire traduire en langage machine (on
dit assembler) doit être placé dans un fichier texte (avec l'extension .ASM sous DOS).
La saisie du programme source au clavier nécessite un programme appelé éditeur de texte.
L'opération d'assemblage traduit chaque instruction du programme
source en une instruction machine. Le résultat de l'assemblage est enregistré dans un fichier
avec l'extension .OBJ (fichier objet).
Le fichier .OBJ n'est pas directement exécutable. En effet, il arrive
fréquemment que l'on construise un programme exécutable à partir de plusieurs fichiers
sources. Il faut (relier) les fichiers objets à l'aide d'un utilitaire nommé éditeur de lien (même si l'on a
qu'un seul). L'éditeur de liens fabrique un fichier exécutable, avec l'extension .EXE.
Le fichier .EXE est directement exécutable. Un utilitaire spécial du système d'exploitation (DOS ici),
le chargeur est responsable de la lecture du
fichier exécutable, de son implantation en mémoire principale, puis du lancement du
programme.
Donc en conclusion pour assembler un programme on doit passer par les phases suivantes :
- Saisie du code source avec un éditeur de texte.
- Compiler le programme avec un compilateur.
19
- Editer les liens pour avoir un programme exécutable. Les trois phases sont schématisées par la
figure suivante
:
Remarque 1 :
On ne peut passer du code source vers le code objet que si le programme source ne présente
aucune erreur.
La saisie se fait par des logiciels qui s'appellent éditeurs de texte, donc on peut utiliser n'importe
quel éditeur de textes (tel que EDLINE sous MSDOS de Microsoft) sauf les éditeurs sous
Windows car ces éditeurs ajoutent dans le fichier des informations (la taille des caractères,
la police utilisée, la couleur etc...) que l'assembleur ne peut pas comprendre .Pour utiliser
les éditeurs sous Windows il est conseiller d'enregistrer les fichiers sous forme RTF.
Editeur de lien :
permet de lier plusieurs codes objets en un seul exécutable.
permet d'inclure des fonctions prédéfinies dans des bibliothèques.
Plusieurs logiciels permettent le passage entre les trois phases présentée dans la figure précédente
on peut citer : MASM (Microsoft Assembler : avec LINK comme
éditeur de lien), TASM (Turbo assembler : avec TLINK comme éditeur de lien) et NASM etc ...
Remarque 2 :
On peut générer à partir d'un fichier objet d'autres formes de fichier pour des systèmes autres que
l'ordinateur (compatible IBM). Les formes les plus connues sont INTEL HEX, ASCII HEX etc ...
Remarque 3 :
L'assembleur est utilisé pour être plus prés de la machine, pour savoir
exactement les instructions générées (pour contrôler ou optimiser une opération) On retrouve
l'assembleur dans :
- la programmation des systèmes de base des machines (le pilotage du clavier, de l'écran, etc...),
- certaines parties du système d'exploitation,
20
- le pilotage de nouveaux périphériques (imprimantes, scanners, etc..
- l'accès aux ressources du système,
L'avantage donc de l'assembleur est de générer des programmes efficaces et rapides (à l'exécution)
par contre ses inconvénients : développement et mise au point long.
II ) Le fichier source (code source) :
Comme tout programme, un programme écrit en assembleur
(programme source) comprend des définitions, des données et des instructions, qui
s'écrivent chacune sur une ligne de texte.
Les données sont déclarées par des directives, mots clefs spéciaux que
comprend l'assembleur (donc ils sont destinés à l'assembleur. Les instructions (sont
destinées au microprocesseur)
II-1 ) Les instructions :
La syntaxe des instruction est comme suit :
{Label :} Mnémonique {opérande} { ; commentaire}
- Le champ opérande est un champ optionnel selon l'instruction (parfois l'instruction
nécessite une opérande et parfois non).
- Le champ commentaire : champ sans signification syntaxique et
sémantique pour l'assembleur , il est optionnel mais très intéressant
lorsque on programme en assembleur, en effet les instructions en assembleur sont des
instructions élémentaires donc dans un programme le nombre d'instructions et assez élevé (par
exemple pour utiliser des fonctions
tels que COS ou SIN il faut réaliser ça en utilisant des opérations arithmétiques et logiques de
base) donc contrairement au langage évolué de
programmation dans les programmes source on va trouver plus d'instructions. Ce qui va
rendre la compréhension des programmes assez délicate et difficile. Pour cette raison lorsque on
programme en assembleur il vaut mieux mettre des commentaires pour que le programme soit lisible
pour les utilisateurs.
Remarque :
Les commentaires sont mis en général dans les passages délicats.
- Le champ Label (étiquette) est destiné pour marquer une ligne qui sera la cible d'une instruction de
saut ou de branchement. Une label peut être formée par 31 caractère alphanumérique ({A.. Z} {a.. z}
{0.. 9} {.?@_$}) au maximum .Les noms des registres ainsi que la représentation mnémonique des
instructions et les directives (voir plus loin) ne peuvent être utilisées
comme Label. Le champ Label doit se terminer par ' : ' et ne peut
commencer par un chiffre. De même il n'y a pas de distinction entre minuscules et
majuscules.
Exemple :
ET1 : MOV AX , 500H ; mettre la valeur 500 dans le registre AX
II-2 ) Les directives :
Pour programmer en assembleur, on doit utiliser, en plus des
instructions assembleur, des directives ou pseudo-instructions : Une directive est une
information que le programmeur fournit au compilateur. Elle n'est pas transformée en une instruction
en langage machine. Elle n'ajoute donc aucun octet au programme compilé. Donc les directives sont
des déclarations qui vont guider l'assembleur.
Une directive est utilisée par exemple pour créer de l'espace mémoire pour des variables, pour
définir des constantes, etc...
Pour déclarer une directive il faut utiliser la syntaxe suivante :
{Nom} Directive {opérande} { ; commentaire}
Le champ opérande dépend de la directive
Le champ commentaire a les mêmes propriétés vues dans le
paragraphe précèdent.
Le champ Nom indique le nom des variables : c'est un champ optionnel
(selon la directive).
II-3 /Exemple de directives :
21
III- 3-1 ) Les directives de données :
III-3- 1-1 / EQU :
Syntaxe : Nom EQU Expression
Exemples :
VAL EQU 50 ; assigne la valeur 50 au nom VAL
ET1 EQU VAL* 5 + 1 ; assigne une expression calculer a VAL
III-3- 1-2 ) DB/DW/DD/DF/DP/DQ/DT:
Ces directives sont utilisées pour déclarer les variables : L'assembleur attribue à chaque variable une
adresse. Dans le programme, on repère les variables grâce à leurs noms. Les noms des variables
sont composés d'une suite de 31 caractères au maximum, commençant obligatoirement par une
lettre. Le nom peut comporter des majuscules, des minuscules, des chiffres, plus les caractères @,
et _. Lors de la déclaration d'une variable, on peut lui affecter une valeur initiale.
a° ) DB (Define byte): définit une variable de 8 bits : c a d elle réserve un espace mémoire d'un octet
: donc les valeurs qu'on peut stocker pour cette directive sont comprises entre 0 et 255 ( pour les
nombres non signés ) et de -128 jusqu'à 127 pour les nombres signés .
Syntaxe : Nom DB Expression
Exemple :
Vil DB 12H ; Définit une variable (un octet) de valeur Initiale 12.
Tab DB 18H, 15H, 13H ; définit un tableau de 3 cases
;(3 octet) Qui démarre à partir de l'adresse TAB.
Mess DB 'ISET' ; définit aussi un tableau mais les valeurs de chaque case
;n'est autre que le code ascii de chaque lettre.
Name DB ? ; définit une variable 8 bits de valeur initiale quelconque .
b° ) DW ( define word) : définit une variable de 16 bits : c a d elle réserve un espace mémoire d'un
mot : donc les valeurs qu'on peut stocker pour cette directive sont comprises entre 0 et 65535 ( pour
les nombres non signés ) et de -32768 jusqu'à 32767 pour les nombres signés .
Syntaxe : Nom DW Expression
Exemple :
TT1 DW 500H ; réserve deux cases mémoire (un mot) a partir de l'adresse TT1.
TAB1 DW 10H,11H,14H ; réserve u tableau de 6 cases chaque valeur sera mise sur deux
cases
YY DW ? ; réserve un mot dans la mémoire de valeur initial quelconque.
22
Les opérandes de l'instruction SEGMENT déterminent la manière dont l'éditeur de liens traitera le
segment :
COMMON :
Tous les segments avec l'étiquette (classe) seront placés à la même adresse de base (dans un bloc
contigu) ; des zones du type (COMMON) avec différents noms ((classe)) seront placés l'un derrière
l'autre.
PUBLIC :
Tous les segments avec ce qualificatif seront regroupés dans un seul segment résultant, l'un
derrière l'autre.
STACK :
Un seul segment avec ce qualificatif est accepté, il est destiné à la gestion de la pile.
MEMORY :
Le premier segment portant ce qualificatif sera placé à une position de mémoire en dessus de tout
autre segment; s'il y a d'avantage de segments de ce genre, ils seront traités comme les segments
du type (COMMON).
24
AT :
Les étiquettes définies dans un tel segment sont définies comme étant relatives à la valeur
((adr) ) 16) * 16.
e°/ Alignement de l'adresse de base d'un segment
Il est possible de contrôler la manière dont l'éditeur de liens détermine l'adresse ou sera placé un
segment: on choisit l'alignement du segment (c.a.d de son premier byte).
Les données sont déclarées par des directives, Les directives qui déclarent des données sont
regroupées dans les segments de données, qui sont délimités par les
directives SEGMENT et ENDS.
Les instructions sont placées dans un autre segment, le segment de code. La ligne :
Code SEGMENT
Sert à déclarer le segment code. On aurait aussi bien pu le nommer
(iset) ou (microprocesseur). Ce sera le segment de notre programme. Cette ligne ne sera pas
compilée : elle ne sert qu'à indiquer au compilateur le début d'un segment.
La ligne :
PROG
25
La première instruction du programme (dans le segment d'instruction) doit toujours être repérée par
une étiquette (dans notre cas : PROG). Le fichier doit se terminer par la directive END avec le nom
de l'étiquette de la première instruction (ceci permet d'indiquer à l'éditeur de liens qu'elle est la
première instruction à exécuter lorsque l'on lance le programme).
Comme nous l'avons vu, les directives SEGMENT et ENDS permettent de définir les segments de
codes et de données. La directive ASSUME permet d'indiquer à l'assembleur quel est le segment de
données et celui de codes
(etc...), afin qu'il génère des adresses correctes. Enfin, le programme doit commencer, avant toute
référence au segment de données, par initialiser le registre segment DS (même chose pour : ES et
SS), de la façon suivante :
MOV AX, Data
MOV DS, AX
Remarque:
On n'est pas tenu de rendre aux registres la valeur qu'ils avaient au début de notre programme. En
effet, avant de charger un programme, le
DOS sauvegarde le contenu de tous les registres puis met le contenu des registres généraux (ainsi
que SI, DI et BP) à zéro. Il les restaurera quand il prend la main.
V ) Structure d'un programme en mémoire :
Lorsque l'utilisateur exécute un programme, celui-ci est d'abord
chargé en mémoire par le système. Le DOS distingue deux modèles de programmes
exécutables : les fichiers COM et les fichiers EXE.
La différence fondamentale est que les programmes COM ne peuvent pas utiliser plus d'un segment
dans la mémoire. Leur taille est ainsi limitée à
64 Ko. Les programmes EXE ne sont quant à eux limités que par la mémoire disponible dans
l'ordinateur.
a/ les fichiers COM :
Lorsqu'il charge un fichier COM, le DOS lui alloue toute la mémoire disponible. Si celle-ci est
insuffisante, il le signale à l'utilisateur par un message et annule toute la procédure d'exécution. Dans
le cas contraire, il crée le PSP du programme au début du bloc de mémoire réservé, et copie le
programme à charger à la suite.
Le PSP (« Program Segment Prefix ») est une zone de 256 (100H) octets qui contient des
informations diverses au sujet du programme. C'est dans le PSP que se trouve la ligne de
commande tapée par l'utilisateur. Par exemple,
le PSP d'un programme appelé MONPROG, exécuté avec la commande
(MONPROG monfic.txt /S /H), contiendra la chaîne de caractères suivante :
( monfic.txt /S /H). Le programmeur a ainsi la possibilité d'accéder aux paramètres.
Un programme COM ne peut comporter qu'un seul segment, bien que
le DOS lui réserve la totalité de la mémoire disponible. Ceci a deux conséquences. La
première est que les adresses de segment sont inutiles dans le programme : les offsets seuls
permettent d'adresser n'importe quel
octet du segment. La seconde est que le PSP fait partie de ce segment, ce qui limite à 64 Ko-256
octets la taille maximale d'un fichier COM. Cela implique également que le programme lui-même
débute à l'offset 100h et non à l'offset 0h.
b) les fichiers EXE :
Bien qu'il soit possible de n'utiliser qu'un seul segment à tout faire, la plupart des programmes EXE
ont un segment réservé au code , un ou deux autres aux données, et un dernier à la pile.
Le PSP a lui aussi son propre segment. Le programme commence donc à l'offset 0h du segment de
code et non à l'offset 100h.
Afin que le programme puisse être chargé et exécuté correctement, il faut que le système sache où
commence et où s'arrête chacun de ces segments. A cet effet, les compilateurs créent un en-tête (ou
« header ») au début de chaque fichier EXE. Ce header ne sera pas copié en mémoire. Son rôle
est simplement d'indiquer au DOS (lors du chargement) la position relative de chaque segment dans
le fichier.
26
Intéressons-nous à présent aux valeurs que le DOS donne à ces registres lors du chargement
en mémoire d'un fichier exécutable ! Elles diffèrent selon que le fichier est un programme COM ou
EXE. Pour écrire un programme en assembleur, il est nécessaire de connaître ce tableau par coeur :
Première raison : pour que le programmeur puisse accéder au PSP ! Deuxième raison : parce
qu'un programme EXE peut comporter un nombre
quelconque de segments de données. C'est donc au programmeur d'initialiser ces
registres, s'il veut accéder à ses données.
Les façons de désigner les opérandes constituent les "modes d'adressage". Selon la
manière dont l'opérande (la donnée) est spécifié, 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 7 modes d'adressage :
- Mode d'adressage registre.
- Mode d'adressage immédiat.
- Mode d'adressage direct.
- Mode d'adressage registre indirect.
- Mode d'adressage relatif à une base.
- Mode d'adressage direct indexe.
- Mode d'adressage indexée.
VI -1 ) Mode d'adressage registre :
Ce mode d'adressage concerne tout transfert ou toute opération, entre deux registres de même taille.
Dans ce mode l'opérande sera stockée dans un registre interne au microprocesseur.
Exemple :
Mov AX, BX ; cela signifie que l'opérande stocker dans le registre BX sera transféré vers le registre
AX. Quand on utilise l'adressage registre, le microprocesseur effectue toutes les opérations d'une
28
façon interne. Donc dans ce mode il n'y a pas d'échange avec la mémoire, ce qui augmente la
vitesse de traitement de l'opérande.
Remarque :
Pour les instructions telles que :
MOV AX,-500H ; le signe - sera propager dans
;le registre jusqu'à remplissage de ce dernier.
Exemple dans notre cas MOV AX,-500H donne AX =1111101100000000B MOV BL,-
20H donne BL = 11100000B
VI -3 ) Mode d'adressage direct :
Dans ce mode on spécifie directement l'adresse de l'opérande dans l'instruction .exemple :
29
MOV AX,adr
La valeur adr est une constante (un déplacement) qui doit être ajouté au contenu du registre DS pour
former l'adresse physique de 20 bits.
Remarque :
En général le déplacement est ajouté par défaut avec le registre segment DS pour former
l'adresse physique de 20 bits, mais il faut signaler
qu'on peut utiliser ce mode d'adressage avec d'autres registres segment tel
que ES par exemple , seule la syntaxe en mnémonique de l'instruction change et devient :
MOV AX, ES : adr
VI -4 ) Mode d'adressage registre indirect :
Dans ce mode d'adressage l'adresse de l'opérande est stockée dans un registre qu'il faut
bien évidemment le charger au préalable par la bonne adresse. L'adresse de l'opérande
sera stockée dans un registre de base (BX ou BP) ou un indexe (SI ou DI).
Exemple :
MOV BX,offset adr
MOV AX,[BX]
Le contenu de la case mémoire dont l'adresse se trouve dans le registre BX (c.a.d : Adr) est
mis dans le registre AX
Remarque:
Le symbole [ ] design l'adressage indirect.
Remarque :
Les syntaxes suivantes sont identiques :
MOV AX,[BX+2] MOV AX,[BX]+2
MOV AX,2[BX]
I ) introduction :
On peut diviser les instructions du 8086/88 en 6 groupes comme suit :
Exemple :
II-1-3 ) POP :
II-1-4 ) PUSHA :
Cette instruction permet d'empiler la totalité des registres internes du microprocesseur sur la pile.
II-1-5 ) POPA :
Cette instruction permet de dépiler la totalité des registres internes du microprocesseur sur la
pile.
II-1-6 ) XCHG :
Elle permet de commuter la source avec la destination comme suit :
II-1-7 ) XLAT :
Cette instruction est utilisée pour convertir des données d'un code à un autre, en effet elle permet de
placer dans l'accumulateur AL le contenu de la case mémoire adressée en adressage
33
base+décalage (8 bits), la base étant le registre BX et le décalage étant AL lui même dans le
segment DS
(AL)<--------[ (BX) + (AL) ]
Syntaxe : XLAT tab_source
Exemple :
conversion du code binaire 4 bits en un digit hexa codé en ASCII
Tab db ‘0123456789ABCDEF'
MOV AL,1110B ; chargement de la valeur à convertir (07) MOV BX, OFFSET TAB
; pointé sur le tableau
XLAT ; Al est chargé par le code ASCII de ‘E'
II - 2 ) les instructions d'entrées-sorties :
II-2-1 ) IN ) OUT:
Elle permet de récupérer des données d'un port (donc de la périphérie) ou restituer des données à
un port, dans les deux cas s'il s'agit d'envoyer ou de recevoir un octet on utilise l'accumulateur AL, s'il
s'agit d'envoyer ou de recevoir un mot on utilise l'accumulateur AX.
Syntaxe :
IN ACCUMULATEUR, DX
OUT DX, ACCUMULATEUR
Remarque :
DX : contient l'adresse du port.
ACCUMULATEUR : contient la donnée (à recevoir ou à emmètre).
II-3 / Les instructions de transfert d'adresses :
II-3-1 ) LEA (Load Effective Address):
Elle transfert l'adresse offset (décalage) d'une opérande mémoire dans un registre de 16 bits
(pointeur ou index). Cette commande a le même rôle que l'instruction MOV avec offset mais
elle est plus puissante car on peut utiliser avec elle toute technique d'adressage.
Exemple :
LEA BX, TAB_VAL (c'est équivalent à MOV BX, offset TAB_VAL)
II-3-2 ) LDS ) LES :
Cette instruction permet de charger le segment et l'offset d'une adresse
Exemple :
Au lieu de faire :
MOV BX, offset tab_val
MOV AX , Seg tab_val
MOV DS , AX
On remplace ces trois instructions par une seule :
LDS BX , tab_val ;elle charge automatiquement l'offset de tab_val dans le registre BX
;et le segment dans le registre DS .
Remarque :
Pour l'instruction LES : le segment est ES.
II-4 ) Les instructions d'indicateur :
II-4-1 ) LAHF ) SAHF :
LAHF : Load AH from Flags : place l'octet de poids faible du registre d'état (FLAGS) dans le registre
AH comme suit :
SA
HF : Store AH into Flags : Place le contenu de AH dans l'octet de poids faible du registre d'état
(FLAGS).
II-4-2 ) PUSHF ) POPF:
PUSHF : Permet d'empiler la totalité du registre d'état (FLAGS)
POPF : Permet de dépiler le registre d'état (FLAGS).
III ) Instructions arithmétiques :
Les instructions arithmétiques peuvent manipuler quatre types de nombres :
Les nombres binaires non signés
34
Les nombres binaires signés.
Les nombres décimaux codés binaires (DCB), non signés.
Les nombres DCB non condensés, non signés.
Les instructions arithmétiques sont divisées en quatre sous-groupes comme le montre le tableau
suivant :
III-1 ) Addition :
III-1-1 ) ADD: (Addition)
Syntaxe : ADD Destination, source
Elle permet d'additionner le contenu de la source (octet ou un mot) avec celui de la destination le
résultat est mis dans la destination
Destination <---------- Destination + source
Exemples :
ADD AX, BX ; AX = AX + BX (addition sur 16 bits) ADD AL,BH
; AL = AL + BH (addition sur 8 bits )
ADD AL, [SI] ; AL = AL + le contenu de la case mémoire
; pointé par SI
ADD [DI], AL ; le contenu de la case mémoire pointé par DI
; Est additionnée avec AL, le résultat est mis
; dans la case mémoire pointé par DI
Remarques :
Ici on a presque les mêmes restrictions de l'instruction MOV c.a.d on n'a pas le droit
d'additionner deux cases mémoires sans utiliser un registre de données.
Exemples :
ADD Tab1 , Tab2
sera remplacé par :
35
MOV AX , Tab2
ADD Tab1 , AX
De même une valeur immédiate ne peut être une destination.
III-1-2 ) ADC : (Addition avec retenue)
Syntaxe : ADC Destination, source
Elle permet d'additionner le contenu de la source (octet ou un mot) avec celui de la destination et la
retenue (CF) le résultat est mis dans la destination
Destination <------------ Destination + source + retenue
Exemples :
ADC AX,BX ; AX = AX + BX + CF(addition sur 16 bits )
ADC AL,BH ; AL = AL + BH + CF(addition sur 8 bits )
ADC AL,[SI] ; AL = AL + le contenu de la case mémoire pointé par SI + CF
ADC [DI],AL ; le contenu de la case mémoire pointé par DI
; est additionné avec AL + CF , le résultat est
; mis dans la case mémoire pointé par DI
Remarque :
Les restrictions de l'instruction ADD sont valables pour l'instruction ADC.
III-1-3 ) INC : (Incrémentation)
Syntaxe : INC Destination
Elle permet d'incrémenter le contenu de la destination
Destination <---------- Destination + 1
Exemples :
INC AX ; AX = AX + 1 (incrémentation sur 16 bits).
INC AL ; AL = AL +1 (incrémentation sur 8 bits).
INC [SI] ; [SI] = [SI] + 1 le contenu de la case mémoire pointé par SI sera
incrémenter
Remarque :
On ne peut pas incrémenter une valeur immédiate.
III-1-4 ) AAA ) DAA : ( ASCII ) DECIMAL Adjust for Addition )
L'addition de deux nombres BCD génére parfois un résultat qui n'est pas un nombre en BCD d'ou il
faut faire des corrections sur ces nombres pour avoir un résultat cohérent. Cette instruction examine
le quarte bas de AL et vérifie s'il est conforme ou non :
Les indicateurs affectés par cette opération sont : AF, CF, OF, PF, SF, ZF
Elle soustrait la source de la destination , qui peut être un octet ou un mot , le résultat n'est pas mis
dans la destination , en effet cette instruction
touche uniquement les indicateurs pour être tester avec une autre instruction ultérieure de saut
conditionnel
Les indicateurs susceptibles d'être touché sont : AF, CF, OF, PF, SF, ZF
Donc cette instruction va nous permettre de comparer deux nombres comme le montre le tableau
suivant :
Elle est identique à l'instruction AAA/DAA mais l'ajustement se fait en BCD pour la soustraction.
III-3 ) La multiplication :
III-3-1 ) MUL : (Multiplication pour les nombres non signés)
MUL effectue une multiplication non signée de l ‘opérande source avec l'accumulateur :
Syntaxe : MUL Source 38
-Si la source est un octet alors elle sera multipliée par l'accumulateur AL le résultat sur 16 bits
sera stocké dans le registre AX.
Si la source est un mot alors elle sera multipliée avec l'accumulateur AX le résultat de
32 bits sera stocké dans la paire des registres AX et DX
Remarque :
Cette multiplication traite les données en tant que nombres non signés
Donc on aura :
Remarque :
Comme AAA et AAS cette instruction va nous permettre de corriger le résultat d'une multiplication
de deux nombres en BCD, pour corriger le résultat de l'instruction AAM divise AL par 10.
Exemple :
MOV AL , 6
MOV DL , 8
MUL DL
AAM
III-4 ) La division :
III-4-1 ) DIV : (Division des nombres non signés)
Syntaxe : DIV Source
Elle effectue une division non signée de l'accumulateur par l'opérande source :
Exemples :
Si l'opérande est un octet : alors on récupère le quotient dans le registre AL et le reste dans le
registre AH.
Si l'opérande est un mot : alors on récupère le quotient dans le registre AX et le reste dans le
registre DX
A/
MOV AH,00h
MOV AL,33H
MOV DL,25H
DIV DL ; Cela implique que AH= et AL =
B/
MOV AX,500H
MOV CX,200H
DIV CX ;Cela implique que AX= et AL =
III-4-2 ) IDIV : (Division des nombres signés )
Syntaxe : IDIV Source
A/
MOV AH,00h
MOV AL,-33H
MOV DL,25H
IDIV DL ; Cela implique que AH= et AL = 40
B/
MOV AX,-500H
MOV CX,200H
IDIV CX ; Cela implique que AX= et AL =
III-4-3 ) AAD : (ASCII Adjust for Division )
Pour corriger le résultat elle va multiplier le contenu de AH par 10 et l'ajoute à celui de AL
Remarque :
Pour cette instruction il faut faire l'ajustement avant l'instruction de division.
III-4-4 ) CBW (convert byte to word)
Cette instruction permet de doubler la taille de l'opérande signé
Octet ------------> Mots
Remarque :
CBW reproduit le bit 7 (bits de signe) de AL dans AH jusqu'à remplissage de ce dernier.
Exemple :
MOV AL, +96 ; AL=0110 0000
CBW ; AH=0000 0000 et AL=0110 0000
Exemple :
MOV AX, 500 ; AX = 0000 0101 0000 0000
NOT AX ; AX = 1111 1010 1111 1111
Une procédure est une suite d'instructions effectuant une action précise, qui sont
regroupées par commodité et pour éviter d'avoir à les écrire à plusieurs reprises dans le
programme.
Les procédures sont repérées par l'adresse de leur première instruction, à laquelle on
associe une étiquette en assembleur.
L'exécution d'une procédure est déclenchée par un programme appelant. Une procédure
peut elle-même appeler une autre procédure, et ainsi de suite.
CALL adresse_debut_procedure
L'adresse est sur 16 bits, la procédure est donc dans le même segment
d'instructions. CALL est une nouvelle instruction de branchement inconditionnel.
La fin d'une procédure est marquée par l'instruction RET :
V-1-2 ) RET :
RET est aussi une instruction de branchement : le registre IP est modifié pour revenir à la
valeur qu'il avait avant l'appel par CALL. Comment le processeur retrouve-t-il cette valeur
? Le problème est compliqué par le fait que l'on peut avoir un nombre quelconque
d'appels imbriqués, comme sur la figure suivante :
46
L'adresse de retour, utilisée par RET, est en fait sauvegardée sur la pile par l'instruction
CALL. Lorsque le processeur exécute l'instruction RET, il dépile l'adresse sur la pile
(comme POP), et la range dans IP.
Empiler la valeur de IP. A ce moment, IP pointe sur l'instruction qui suit le CALL.
Placer dans IP l'adresse de la première instruction de la procédure (donnée en
argument).
Et l'instruction RET :
Remarque 1 :
(paramètres) qui sont fournies par le programme appelant, et produit un résultat qui est
transmis à ce programme. Plusieurs stratégies peuvent être employées :
1. Passage par registre : les valeurs des paramètres sont contenues dans des registres
du processeur. C'est une méthode simple, mais qui ne convient que si le nombre de
paramètres est petit (il y a peu de registres).
2. Passage par la pile : les valeurs des paramètres sont empilées. La procédure lit
la pile.
Convenons que les entiers sont passés par les registres AX et BX, et que le résultat sera
placé dans le registre AX.
Cette technique met en œuvre un nouveau registre, BP (Base Pointer), qui permet de lire
des valeurs sur la pile sans les dépiler ni modifier SP. Le registre BP permet un mode
d'adressage indirect spécial, de la forme :
MOV AX, [BP+6]
La procédure SOMME2 va lire la pile pour obtenir la valeur des paramètres. Pour cela, il
faut bien comprendre quel est le contenu de la pile après le CALL :
empilée par CALL). Chaque élément de la pile occupe deux octets. La procédure
SOMME2 s'écrit donc :
48
SOMME2 PROC near ; AX <- arg1 + arg2
MOV BP, SP ; adresse sommet pile
MOV AX, [BP+2] ; charge argument 1
ADD AX, [BP+4] ; ajoute argument 2
RET
SOMME2 ENDP
La valeur de retour est laissée dans AX.
La solution avec passage par la pile parait plus lourde sur cet exemple simple. Cependant, elle est
beaucoup plus souple dans le cas général que le passage par registre. Il est très facile par exemple
d'ajouter deux paramètres supplémentaires sur la pile. Une procédure bien écrite modifie le moins de
registres possible. En général, l'accumulateur est utilisé pour transmettre le résultat et est donc
modifié. Les autres registres utilisés par la procédure seront normalement sauvegardés sur la pile.
Voici une autre version de SOMME2 qui ne modifie pas la valeur contenue par BP avant l'appel :
JMP cible
Si le JMP est de type FAR alors CS et IP sont remplacé par les nouvelles valeurs obtenues à partir
de l'instruction.
L'exécution de l'instruction MOV BX, AX sera faite après l'exécution de la boucle 5 fois.
V-3-2 ) LOOPE ) LOOPZ : (boucle si égale ou si égale à zéro) : Le registre CX est décrémenter de 1
automatiquement
Si CX est différent de zéro et ZF=1 alors IP = IP + déplacement
Elles permettent de travailler sur des blocs d'octets ou de mots allant jusqu'à 64 Koctet.
Remarque :
Ces blocs peuvent être des valeurs numériques ou alphanumériques.
VI -1 ) Les préfixes de répétitions :
VI-1-1 ) REP :
Ces instructions sont utilisées avec les instructions de chaînes de caractères pour assurer la
répétition de l'instruction si on veut appliquer l'instruction sur un ensemble d'informations.
REP décrément automatiquement CX est test est ce qu'il est égal à zéro ou non. Si CX = 0 REP
s'arrêt
Syntaxe :
STOS chaine_destination
STOSB
STOSW
53
STOS transfert un octet ou un mot du registre AL ou AX vers l'élément de chaîne adressé par DI et
modifie DI pour qu'il pointe vers l'emplacement suivant de la chaîne.
Exemple :
transfert d'une chaîne source vers une chaîne destination en utilisant LODS et STOS.
Donnee SEGMENT
Mess_Sour db ‘bonjour iset de nabeul' ; message source
Donnee ENDS
Extra SEGMENT
Mes_Des db 22 dup (0) ; message destination
Extra ENDS
Code SEGMENT
Assume CS : Code, DS : Donnee, ES : extra
PROG PROC
MOV AX,Donnee
MOV DS, AX
MOV AX,Extra
MOV ES, AX
LEA SI, Mess_Sour ; pointé le message source
LEA DI, Mess_Des ; pointé le message destination
MOV CX, 22 ; nombre de caractère à transfèrer
CLD ; incrémentation automatique du SI et DI
DEBUT : LODSB ; transfert avec le préfixe REP STOSB
LOOP DEBUT
MOV AX, 4C00H ; Retour au DOS INT 21H
PROG ENDP
CODE ENDS
END PROG
VII ) Les instructions de commande du processeur :
Ces instructions agissent sur le processeur et ses indicateurs (Flags) ils sont en nombre de 12
comme le montre le tableau suivant
54
VII-1 ) Indicateurs :
VII-1-1/ STD :
VII-1-2 ) STI :
VII-2-1 ) HALT :
VII-2-2 ) WAIT :
Met le CPU en état d'attente tant que sa ligne de TEST n'est pas active. En effet toutes les cinq
périodes d'horloge le CPU vérifie est ce que cette entrée est active ou non, si elle est active le
processus exécute l'instruction suivante à WAIT.
VII-2-3 ) ESC :
L'instruction Escape fournit un mécanisme par lequel des coprocesseurs peuvent recevoir leurs
instructions à partir de la suite d'instructions du 8086.
VII-2-4 ) LOCK :
Elle utilise dans les systèmes Multiprocesseur en effet elle permet le verrouillage du bus vis-à-vis des
autres processeurs.
Le CPU ne fait rien on peut s'en servir pour créer des temporisations.
Exemple :
I ) Introduction :
55
Un système à base de microprocesseur peut comporter plusieurs périphériques tels que : un
Ecran, une souris, une imprimante, un disque dure, un CNA (convertisseur numérique analogique),
un CAN etc ..
Pour dialoguer avec ces périphériques le microprocesseur a trois façons de communiquer avec
ces derniers :
- En questionnant de façon continue le périphérique pour vérifier que des données peuvent être
lues ou écrites (Polling).
- En l'interrompant lorsqu'un périphérique est prêt à lire ou écrire des données (interruption)
- En établissant une communication directe entre deux périphériques (DMA : Direct memory
acces).
I-1/ Le polling :
Bien que le polling soit une façon simple d'accéder à un périphérique , le débit des données dans un
périphérique est parfois beaucoup plus lent que la vitesse de fonctionnement d'un processeur , et le
polling peut donc être très inefficace . On lui préfère en général la méthode par interruptions.
I-2 ) Le DMA :
En cas de transfert de données de grande quantité entre deux périphériques, il peut être plus
efficace de laisser communiquer entre eux les
deux périphériques plutôt que de solliciter le processeur. Ce type de communication avec les
entrées/sorties s'appelle gestion de transfert par
DMA, Le processeur indique au contrôleur de DMA quels sont les
périphériques qui doivent communiquer, le nombre et éventuellement l'adresse des données à
transférer, puis il initie le transfert. Le processeur
n'est pas sollicité durant le transfert, et une interruption signale au processeur la fin du
transfert.
I-3 ) L'interruption :
Lorsque un périphérique reçoit des données pour le processeur, il envoie au processeur un signal
d'interruption. Si celui-ci peut être interrompu ( à condition qu'il ne soit pas en train de
communiquer avec un périphérique de plus haute priorité) , il stoppe la tâche en cours , sauve son
état ( ces registres) en mémoire (la zone pile ) et appelle la routine correspondant au numéro
d'interruption .
56
Remarque 2 : (plusieurs interruptions):
Le fonctionnement des périphériques se fait en général d'une manière asynchrone, donc plusieurs
interruptions peuvent être déclenchées en même temps, il existe souvent un contrôleur
d'interruptions destiné à gérer les conflits entre interruptions
Une interruption est signalée au processeur par un signal électrique sur une borne spéciale. Lors de
la réception de ce signal, le processeur (traite) l'interruption dès la fin de l'instruction qu'il était en
train d'exécuter. Le traitement de l'interruption consiste soit :
Ces trois entrées permettent l'arrivée d'une demande (interruption externe) extérieur.
L'ordinateur est relié à plusieurs périphériques, mais nous venons de voir qu'il n'y avait
qu'un seul signal de demande d'interruption, INTR. Le contrôleur d'interruptions est un
57
circuit spécial, extérieur au processeur,
dont le rôle est de distribuer et de mettre en attente les demandes d'interruptions
provenant des différents périphériques.
Fonctions BIOS :
Int 1Ah, Fct 02h Date et heure : Lecture de l'horloge temps réel BIOS (> AT) : Cette fonction permet
de lire l'heure de l'horloge temps réel alimentée par batterie. Comme ce type d'horloge n'existe que
sur les AT, seul ce modèle de PC soutient cette fonction.
Entrée :
AH = 02h
Sortie :
Remarques :
- Le contenu des registres BX, SI, DI, BP et des registres de segment n'est pas modifié
par cette fonction. Le contenu de tous les autres registres peut avoir été modifié.
Cette fonction permet de sortir des caractères sur le périphérique de sortie standard ou de les lire sur
le périphérique d'entrée standard. Le
caractère reçu ou écrit chaque fois n'est pas examiné par le système d'exploitation. Rien de
particulier ne se produit donc lorsqu'un caractère Ctrl-C apparaît. Comme l'entrée et la sortie
standard peuvent être redirigées sur d'autres périphériques ou vers un fichier, les caractères sortis
ne doivent pas nécessairement apparaître sur l'écran ni les caractères lus provenir obligatoirement
du clavier. Toutefois, lorsque l'accès se fait sur un fichier, il est impossible pour le programme d'appel
de détecter si tous les caractères de ce fichier ont déjà été lus ou bien si le support (disquette, disque
dur) sur lequel figure ce fichier est déjà plein. Pour l'entrée d'un caractère, la fonction n'attend pas
qu'un caractère soit prêt mais revient immédiatement au programme d'appel dans tous les cas.
60
Entrée :
AH = 06h
DL = 0 - 254 : Sortir ce caractère
DL = 255 : Lire un caractère Sortie :
Pour la sortie de caractères : aucune
Pour l'entrée de caractères :
Flag Zéro =1 : aucun caractère n'est prêt
Flag Zéro =0 : Le caractère entré figure dans le registre AL
Remarques :
Lorsque des codes étendus sont lus, le code 0 est tout d'abord renvoyé dans le
registre AL. La fonction doit être appelée à nouveau pour lire le code étendu lui-même.
- Le caractère de code ASCII 255 ne peut être sorti à l'aide de cette fonction puisqu'il est interprété
comme d'entrée d'un caractère.
- Le contenu des registres AH, BX, CX, DX, SI, DI, BP, CS, DS, SS, ES et du registre de flags n'est
pas modifié par cette fonction.
l'écran :
Entrée :
AH = 09h
DONNEE SEGEMENT
MESSAGE DB ‘ BONJOUR ISET DE NABEUL $',13,10
DONNEE ENDS
CODE SEGMENT
ASSUME CS : CODE , DS : DONNEE
PROG PROC
MOV AX , DONNEE MOV DS , AX
LEA DX , MESSAGE ; Pointé le message par DX MOV AH , 09H
INT 21H ; afficher le message
MOV AX,4C00H ; Retour au DOS
INT 21H
PROG ENDP CODE ENDS END PROG
Remarques :
La chaîne de caractères doit être stockée dans la mémoire sous forme d'une séquence
d'octets correspondant aux codes ASCII des caractères composant la chaîne. La fin de la chaîne de
caractères doit être signalée au DOS à l'aide d'un caractère "$" (code ASCII 36).
- Seul le contenu du registre AL est modifié par l'appel de cette fonction. Exemple de programme
utilisons les interruptions : affichage de l'heure d'un PC :
;*************************************************************************
*******
;*************************************************************************
*******
;****************** Programme affichage de l'heur du PC
*************************
;*************************************************************************
*******
;*************************************************************************
*******
code segment assume cs:code
;*********************** programme principal
************************************
prog proc debut: mov ah,02
int 1aH ; interruption qui permet de lire l'heur du PC
mov bl,ch ; ch = heure
call affiche ; afficher les heurs
mov bl,cl ; cl=minute
call affiche ; afficher les minutes
mov bl,dh ; dh=seconde
call affiche ; afficher les secondes
prog endp ; fin de la procédure principale
mov dl,13 ; retour chariot
mov ah,06
int 21h
jmp debut
affiche proc ; procédure d'affichage d'un nombre BCD
mov dl,bl 62
and dl,0f0h ; masquer pour avoir les dizaines
ror dl,1 ; faire une rotation
ror dl,1
ror dl,1
ror dl,1
add dl,30h ; ajouter 30H pour avoir le code ASCII correct
mov ah,06 ; du chiffre a afficher
int 21h
mov dl,bl
and dl,0fh
add dl,30h
mov ah,06
int 21h
mov dl,':'
mov ah,06
int 21h ret
affiche endp
code ends
end prog
Fonctions Gestionnaire de souris
Int 33h, Fct 00h Réinitialisation du driver de souris Initialise le driver de souris et enclenche ainsi le
test de la souris. Entrée :
AX = 0000h
Sortie :
AX = FFFFh : dans ce cas, un driver de souris est installé
BX = Nombre de boutons de la Souris (à partir de 1.0)
AX = 0000h : erreur, aucun driver de souris n'est installé
Remarques :
L'appel de cette fonction agit sur toute une série de paramètres de la souris qui peuvent
être fixés à l'aide des différentes fonctions de la souris :
- Le curseur de la souris est placé au centre de l'écran puis caché. Il apparaîtra désormais en mode
graphique sous forme d'une flèche, alors qu'il sera représenté en mode de texte sous forme d'une
case de texte en inversion vidéo. Le curseur de la souris est systématiquement affiché dans la page
0 de l'écran, indépendamment du mode. La zone de déplacement sélectionnée est la totalité de
l'écran.
- Les gestionnaires d'événements installés par un programme. Ils sont désactivés.
Int 33h, Fct 01h Afficher le curseur de la souris sur l'écran
Après appel de cette fonction, le curseur de la souris devient visible sur l'écran et suit désormais les
déplacements de la souris sur l'écran.
Entrée :
AX = 0001h
Sortie :
Aucune
Remarques :
L'appel de cette fonction entraîne l'incrémentation d'un compteur interne, en fonction
duquel le curseur de la souris est ou non affiché sur l'écran. Si ce compteur contient la valeur 0, le
curseur de la souris sera affiché sur l'écran, alors que la valeur -1 a pour effet de le faire disparaître
de l'écran. Lorsque la fonction 00h (Reset) est appelée, ce compteur est tout d'abord fixé sur -1, pour
prendre ensuite la valeur 0 lors du premier appel de cette fonction, ce qui se traduit par la
réapparition du curseur sur l'écran.
Int 33h, Fct 03h Lire la position de la souris et l'état des boutons de la souris :
L'appel de cette fonction fournit la position actuelle de la souris et l'état des différents boutons
de la souris.
63
Entrée :
AX = 0003h
Sortie :
Le 8255 est un circuit programmable de 40 broches (voir figure 1) d'interface d'entrée/sortie parallèle
qui a été conçu pour travailler avec les
microprocesseurs de la famille INTEL. Il est formé par trois ports d'entrées/sorties, chaque port
est de 8 bits qui peuvent être programmés en entrée ou en sortie avec trois modes différents (mode
zéro, mode un et mode deux).
Remarque : 64
Le port C est divisé en deux port C haut et port C bas
Le schéma bloque du 8255A est donné par la figure suivante :
Le schéma bloc du 8255 montre bien qu'il est divisé en deux groupes :
Groupe A : formé par le port A et le port C haut.
Groupe B : formé par le port B et le port C bas.
Le registre de données (Data buffer Bus) assure la liaison entre le bus de
données extérieur et le registre de controle ainsi que les ports
d'entrées/sorties.
La sélection du 8255A se fait par l'intermédiaire de la pine CS (qui est en général
fournie par une logique de décodage qui permet la sélection du 8255A : voir plus loin
les exemples d'applications)
Le bus d'adresse du 8255A est formé essentiellement par deux pines (A0et A1) qui
permettent de sélectionner les ports ainsi que le registre de contrôle comme le montre
le tableau suivant :
65
Plus en détail l'adressage des différents ports en entrée sortie se fait selon la table de
vérité suivante :
Le 8255 est connecté avec le système à base de microprocesseur comme le montre la figure
suivante :
En mode zéro les ports du 8255A peuvent être programmés en entrée ou en sortie : 8 bits pour le
port A , 8 bits pour le port B et le port C est formé de deux quartes ( un quarte haut et un quarte bas )
, donc il y a 16 combinaisons possibles :
67
Exemple si on veut configurer le port A en sortie , port B en entrée , portc haut entrée et port C bas
sortie le mot de commande est 93H
Le programme :
MOV AL, 39H ; Mot de commande
MOV DX , adresse_registre_de_commande
OUT DX,AL ; envoi du mot vers le registre de commande
Remarque :
Les sorties sont mémorisées dans des bascules D.
Les entrées ne sont pas mémorisées.
Sur un RESET, tous les ports sont positionnés en mode entrées et il faut les
reprogrammer, si nécessaire.
Les bascules du port C peuvent être mises à 1 ou à 0 individuellement, lorsque
le bit 7 du mot de commande est égal à 0 . Le mot de commande devient alors :
Remarque :
Le battement signifie qu'on allume la diode puis on l'éteint une seule fois car dans notre cas il faut
toujours lire les switches car l'utilisateur peut changer l'état des switches à tout moment.
Le programme de l'application est le suivant :
Donnee SEGMENT
PortA EQU 300H
PortC EQU 302H
Reg_com EQU 306H
Mot_com EQU 91H
Masque_SW0 EQU 01H
Diode_allume EQU 0FH
Diode_etainte EQU 00H
Donnee ENDS
Code SEGMENT
Assume CS :code , DS :donnee
Prog Proc
MOV AX,donnee ; pointer le data segment
MOV DS,AX
MOV AL,Mot_com ; configurer les ports en sorties
OUT Reg_com,AL
DEBUT: IN AL,PortC
AND AL,03H
CMP AL,01
JZ Diode_paire ; si SW=1 alors battement paire
72
CMP AL,02
JZ Diode_impaire ; si SW=1 alors battement impaire
JMP DEBUT
Diode_paire : MOV AL,05H ; Battement des diodes paire
OUT PortA,AL
CALL Tempo ; Temporisation
MOV AL,00H
OUT PortA,AL
CALL Tempo ; Temporisation
JMP DEBUT
Diode_impaire : MOV AL,0AH ; Battement des diodes impaire
OUT PortA,AL
CALL Tempo ; Temporisation
MOV AL,00H
OUT PortA,AL
CALL Tempo ; Temporisation
JMP DEBUT
MOV AX,4C00H
INT 21H
Prog endp
Tempo : MOV CX,7FFFH ; Effectuer une temporisation
Temp1: PUSh CX ; avec deux boucles imbriqués
MOV CX,7FFFH
Temp2: NOP
NOP
NOP
NOP
LOOP Temp2
POP CX
LOOP Temp1
RET
Code ends
End prog
Exemples 2 :
On donne le schéma de la figure suivante :
On suppose que les adresses des ports est donner comme suit : 73
Port A : 300H
Port B : 302H
Port C : 304H
Registre de commande : 306
Donner l'organigramme ainsi que le programme qui permet de générer le signal suivant :
Donnee SEGMENT
PortA EQU 300H
Reg_com EQU 306H
Mot_com EQU 91H
Donnee ENDS
Code SEGMENT
Assume CS :code , DS :donnee
Prog Proc
MOV AX,donnee ; pointer le data segment
MOV DS,AX
74
MOV AL,Mot_com ; configurer les ports en sorties
OUT Reg_com,AL
DEBUT1: XOR AL,AL
DEBUT2:OUT PORTA,AL
CALL Tempo ; Si on augmente la temporisation
INC AL ; on augmente la pente du signal
CMP AL,0FFH ; et bien sur la période T
JNZ DEBUT2
JMP DEBUT1
Prog endp
Tempo : MOV CX,7FFFH ; Effectuer une temporisation
Temp1: PUSh CX ; avec deux boucles imbriqués
MOV CX,7FFFH
Temp2: NOP
NOP
NOP
NOP
LOOP Temp2
POP CX
LOOP Temp1
RET
Code ends
End prog
Exemple 3 :
Enfin Rd/Rw : c'est pour donner l'ordre de lecture ou écriture sur LCD. Parmis les commandes on
trouve :
Exemple de programme qui affiche le message ‘bonjour iset n' sur LCD
Avant de commencer le programme il faut déterminer les mots qu'il faut envoyer au portB pour
valider une donnée ou valider une commande d'où le tableau suivant :
On suppose que les adresses des ports est donner comme suit :
Port A : 300H
Port B : 302H
Port C : 304H
Registre de commande : 306H
Donnee SEGMENT
Message db ‘bonjour iset n'
PortB EQU 302H
PortC EQU 304H
Reg_com EQU 306H
Mot_com EQU 80H
Donnee ENDS
Code SEGMENT
Assume CS :code , DS :donnee
Prog Proc
MOV AX,donnee ; pointer le data segment
MOV DS,AX
MOV AL,Mot_com ; configurer les ports en sorties
OUT Reg_com,AL 76
LEA SI,message ; Pointe le message à afficher
MOV CX,14 ; on 14 caractère à afficher
CALL Init_LCD ; initialisation de l'LCD
DEBUT :
MOV AL,[SI] ; programme principal
OUT PortC,AL ; envoie de la donnée
CALL Vali_donnée ; validation de la donnée
INC SI
LOOP DEBUT
Init_LCD : MOV AL,01 ; effacer LCD
OUT PortC,AL
CALL Vali_commande ; Validation de l'effacement
MOV AL,0EH ; effectuer un Home pour LCD
OUT PortC,AL
CALL Vali_commande ; Valide le HOME
MOV AL,06 ; Ecriture vers la droite
OUT PortC,AL
CALL Vali_commande ; valide le mode d'écriture.
RET
Vali_commande :
MOV AL,04 ; Sous programme validation
OUT PortB,AL ; de la commande
MOV AL,00
OUT PortB,AL
RET
Vali_donnée :
MOV AL,05 ; Sous programme validation
OUT PortB,AL ; de la donnée
MOV AL,01
OUT PortB,AL
RET
MOV AX,4C00H
INT 21H
Prog endp
Exemple 4 : Commande d'un moteur Pas à Pas
On donne le schéma de la figure suivante :
77
Les différentes phases sont les suivantes (en mode avancement par un pas):
Les différentes phases sont les suivantes (en mode avancement par demi pas):
78
La commande des phases du moteur pas à pas bipolaire a aimant permanent est donnée par
le tableau suivant :
D'où le programme par exemple qui fait tourner le moteur pas à pas de 90° : On suppose que les
adresses des ports est donner comme suit :
Port A : 300H
Port B : 302H
Port C : 304H
Registre de commande : 306H
1 pas = 0.9°
A+ est connecté avec PA0
B+ est connecté avec PA1
A- est connecté avec PA2
B- est connecté avec PA3
Le programme est comme suit :
Donnee SEGMENT
Phase db 03H, 06H, 0CH, 09H, 03H, 06H, 0CH, 09H
PortA EQU 300H
Reg_com EQU 306H
Mot_com EQU 80H
Donnee ENDS
Code SEGMENT
Assume CS : code, DS :donnee
Prog Proc
MOV AX,donnee ; pointer le data segment
79
MOV DS,AX
MOV AL,Mot_com ; configurer les ports en sorties
OUT Reg_com, AL
MOV CX, 100 ; 100 * 0.9° = 90°
DEBUT1 : LEA SI, phase ; Pointer sur le tableau des phases
DEBUT2 : MOV AL,[SI]
OUT portA, AL ; Envoie des différentes phases
INC SI
CMP SI,7
JNZ DEBUT2
LOOP DEBUT1
MOV AX, 4C00H ; Retour au DOS INT 21H
Prog endp
Code ENDS
END PROG
II-2 ) Le Mode 1 du 8255A :
En mode 1 , les ports A et B sont utilisés en entrée ou en sortie gérées par les accès du portC .
Mode 1 : en entrée :
En entrée les ports A et B sont configurés en entrée alors que le PC0, PC1 et Pc2 assure le
handshake pour B et PC3, PC4 et Pc5 pour le A (PC6 et PC7 peuvent être programmés en entrée ou
en sortie). STB : (Strobe input) : Au niveau bas , charge les données dans le verrou d'entrée . IBF
: (Input Buffer Full) : Au niveau haut les données ont été verrouillées :
IBF = 1 par STB au niveau 0
IBF = 0 par le front montant d'un RD (read) INTR : (Interrupt Request) : Au niveau
haut : demande d'interruption vers le microprocesseur :
INTR = 1 par STB=1, IBF=1 et INTE=1
INTR =0 par le front descendant d'un RD (read)
Remarque :
Le signal INTE est contrôlé par le mot de commande du portC (PC4 pour le Port A et PC2 pour le
Port B)
Le handshak en entrée est résumé par cette figure :
Au départ la périphérie charge les données dans les verrous d'entrée du 8255 (STB=0) puis le 8255
répond au périphérique par : chargement fait (IBF=1). Enfin le 8255 peut interrompre le
fonctionnement du microprocesseur pour lui signaler qu'il a des données à prendre (INTR=1)
La figure suivante illustre ce mode de fonctionnement pour les portA et portB avec leur mot de
commande respectif.
Remarque :
On ne trouve plus dans ce cas l'organisation symétrique du portc (c,a,d portc haut et portc bas)
80
Mode 1 : en sortie :
OBF : (Output Buffer Full) : Devient égale à 0 quand le microprocesseur a écrit des
données dans le port, et elle revient à 1 sur le front montant de WR et à 0 sur ACK à zéro.
ACK : (Acknowledge Input) : = 0 signifie que les données ont été acquises.
INTR : (Interrupt Request) : =1 demande d'interruption vers le microprocesseur :
* Mise à 1 par ACK, avec OBF=1 et INTE=1
* Mise à zéro par le front descendant de WR
Donc on peut schématisé le transfert par la figure suivante :
81
La figure suivante illustre ce mode de fonctionnement pour les portA et portB avec leur mot de
commande respectif.
Remarque :
Le port A ainsi que le Port B peuvent être mis en entrée ou en sortie individuellement
dans le mode 1 : c'est le mode mixte
Pour connecter une interface de 8 bits (le 8255A) avec un bus de données de 16 bits (Le 8086) il faut
prendre des précautions en effet on a vu dans le paragraphe «
organisation physique de la mémoire » qu'avec le microprocesseur 8086 si on accède à une
adresse paire les données serons transmises sur le bus de données D0-D7 mais si on accède à une
adresse impaire les données seront transmises sur D8-D15, Or avec la mémoire on veut que le Bank
0 est connecte au signal BHE et le bank1 est lié avec A0 ( pine d'adresse). Dans le cas du 8255 on a
le même problème qu'il faut résoudre lorsque on veut connecter cette interface avec un
microprocesseur 8086.on prenons en considération le tableau suivant :
84
1er solution : utilisation des adresses paires : c'est-à-dire que les pines A1 et A2 du
microprocesseur seront connecté respectivement au pine A0 et A1 du 8255. Le schéma de la
solution est donné comme suit :
I ) Introduction :
Simplexe.
Half duplexe
Full duplexe
Remarque :
La vitesse de transmission est mesurée en bps (bits par seconde), mais aussi BAUD (nombre des
changements du signal par Seconde). Il existe 2 types de Communications
Série: Synchrone et Asynchrone :
La cadence de transmission est fixée par une horloge dont la période donne le temps de
transmission de 1 bit.
Au repos, la ligne de transmission est à l'état 1. Le début de transmission est signalé par l'apparition
du bit de départ qui est dans l'état logique 0 (START). Les bits de donnée sont ensuite transmis
séquentiellement. Un bit de parité est ajouté éventuellement à la suite des bits de donnée pour
vérifier la bonne transmission des données en effet il permet de détecter des erreurs de
transmission. La fin de transmission du caractère est signalée par un ou plusieurs bits d'arrêt à l'état
1 (bits STOP). Le bit de départ permet au récepteur de
détecter l'arrivée d'un caractère et de recaler la phase de l'horloge de réception afin
d'échantillonner correctement les bits suivants (au milieu de chacun des bits). Ainsi, comme les
fréquences d'émission et de réception ne
sont pas strictement identiques, il suffit de garantir une précision de quelques pour-cent pour
assurer une réception valide. Les vitesses normalisées sont : 50, 75, 110, 150, 300, 600, 1200,
2400,4800, 9600, 19200, 38400 bauds.
Le composant électronique chargé de la gestion des transmissions séries asynchrones dans les PC
est appelé UART (Universal Asynchronous Receiver Transmitter).le circuit qui gère cette
communication est le 8250 de National Semiconductor ou son équivalent le 16550 dont le brochage
est comme suit :
La vitesse n'est pas programmée directement dans l'UART - c'est un circuit comparable à une
horloge (baud rate generator) qui se charge de réguler celle-ci.
90
EXEMPLE : pour régler l'UART à une vitesse de 9600 bauds, il faudra copier 0x0C vers DLR.
III - 2 ) Les registres de contrôle de la ligne
Ils sont au nombre de trois, et permettent de connaître l'état de la ligne ou du modem, et de
réinitialiser celui-ci :
III - 2 - 1 ) LSR - Line Status Register (registre d'état de la ligne)
Les valeurs de ce registre correspondent aux broches de l'interface. Les bits 0 à 3 indiquent les
variations depuis la dernière lecture du processeur du registre - ils seront forcés à 1 si il y a eu
changement. Toutes leurs valeurs sont réinitialisées, s'il y a lieu, à un 0 logique dès que le
processeur a achevé une lecture du registre. Les bits 4 à 7 contiennent, quant à eux, l'état actuel de
diverses données de la ligne.
DCTS (Delta Clear To Send) : variation d'état de la broche CTS (préparation d'émission)
DDSR (Delta Data Set Ready) : variation d'état de la broche DSR (données prêtes)
TERI (Trailing Edge of Ring Indicator) : entrée RI de l'UART (Ring Indicator). Ce bit passe à 1
si RI passe de ON (0) à OFF (1). Un appel a été détecté depuis la dernière lecture.
DRLSD (Delta Received Line Signal Detector) : variation d'état de l'entrée RLSD de
l'UART. Indique si la liaison avec le modem distant a été établie.
CTS (Clear To Send) : état de la broche CTS.
DSR (Data Set Ready) : état de la broche DSR.
RI (Ring Indicator) : signale un appel sur la ligne.
RLSD (Receive Line Signal Detect) : indique si la liaison avec le modem distant a été établie.
III-2-3 ) MCR - Modem Control Register (registre de contrôle du modem)
91
Les bits OUT1, OUT2, RTS et DTR permettent, en forçant leur valeur, de
contrôler la valeur barre des signaux correspondants (DTR et RTS correspondent à des
broches de l'interface, OUT1 et OUT2 sont des sorties auxiliaires).
III- 3 ) Les registres de contrôle d'interruptions
On pourra par le biais de ces registres déclarer quels événements
déclencheront une interruption. Une fois l'interruption détectée dans le programme, on pourra
définir sa cause, et y répondre.
III - 3 - 1 ) IER - Interrupt Enable Register (registre d'autorisations d'interruptions) :
Le bit DLAB du registre LCR (registre de contrôle de ligne) doit être forcé à 0 pour pouvoir accéder à
ce registre. Les quatre bits de poids faible (bits 0 à 3) permettent, lorsqu'ils sont forcés à 1, de
générer une interruptions lors de l'apparition de l'événement associé - on pourra retrouver la cause
de cette interruption dans le registre IIR. La liste ci-dessous définit quels événements associés avec
les bits de ce registre :
Les trois bits IID (Interrupt ID) permettent de connaître la cause de l'interruption, sa priorité, et
le moyen de désactiver l'interruption. Le tableau
suivant fournit la liste des combinaisons de ces trois bits et leur signification :
III-4 ) Les registres de transfert 91
III-4-1 ) Les registres d'émission
Lorsqu'un caractère doit être transmis, il doit d'abord être transféré dans le registre THR
(Transmission Holding Register = registre d'attente de l'émetteur). Il y restera tant que le caractère
précédent ne sera pas acquitté par la machine distante. Une fois l'acquittement reçu, le caractère
sera transféré dans un autre registre :
· Ce registre est à écriture seule (il possède la même adresse que RBR, le registre de réception : un
ordre de lecture à l'adresse de THR renverra donc le contenu de RBR)
· Le bit DLAB du registre LCR (contrôle de la ligne) doit être forcé à 0 pour pouvoir effectuer une
écriture dans ce registre.
· Ce registre est sur 8 bits. On pourra y envoyer de 5 à 8 bits, suivant les réglages du registre de
contrôle de ligne LCR (bits WLS), sachant que ce sera le bit 0 (poids le plus faible) qui sera le
premier transmis.
· il sera judicieux d'effectuer une lecture de LSR (registre d'état de la ligne) - bits 5 et 6 - pour savoir
quand le registre THR devient libre, et quand le caractère présent dans TDR a été transmi totalement
sur la ligne .
L'octet reçu sera transféré (sans ses bits de parité et de stop) dans le registre RBR (Receiver Buffer
Register = registre de réception). De la même manière qu'avec les registres d'émission, il existe un
registre de transit - appelé RDR - par lequel le bit reçu passera en premier, avant d'être
débarrassé de ses bits de contrôle.
Remarque :
· Le registre RBR est à lecture seule. les registres d'émission THR et de réception RBR possèdent
une adresse commune. Ainsi une écriture sur l'adresse de RBR provoquera un remplissage du
registre THR, et n'aura aucun effet sur le registre de réception.
· Le bit DLAB du registre LCR (contrôle de la ligne) doit être forcé à 0 pour pouvoir effectuer une
lecture dans ce registre.
· Ce registre est sur 8 bits : y seront copiés les 5 à 8 bits de données, sans bits de contrôle. Le bit 0,
de poids le plus faible, est le premier à avoir été reçu.
· il sera judicieux d'effectuer une lecture de LSR (registre d'état de la ligne) - bits 0 à 4 - pour
détecter les éventuelles erreurs de transmission, ou tout simplement pour savoir si un caractère a été
reçu-se reporter à la partie traitant de ce registre.
IV Exemple de programmation du 8250/16550 :
IV-1 ) Programmation directe :
Exemple de programme qui permet de lire un caractère du port COM1 par polling :
LSR EQU 3FDH
TXRX EQU 3F8H
RDA EQU 01H
TBE EQU 20H
DEBUT : IN AL, LSR ; Lecture de LSR
TEST AL, RDA ; tester RDA
JZ DEBUT ; if not RDA
93
IN AL, TXRX ; lecture de la donnée
EXAMPLE 2: Ecriture d'un caractère sur le port COM1 :
DEBUT :
IN AL, LSR ; Lecture LSR
TEST AL, TBE ; tester TBE
JZ DEBUT
MOV AL, 'a' ; caractère à transmettre
OUT TXRX, AL ; envoie caractère sur le port
IV-2 ) Programmation en utilisant les interruptions BIOS/ DOS :
L'interruption 21H (DOS):