CHAPITRE IV
La PROGRAMMATION en ASSEMBLEUR du
MICROPROCESSEUR 8086
Généralités
Chaque microprocesseur
reconnait un ensemble d’instructions appelé jeu d’instructions
(Instruction Set) fixé par le constructeur.
Pour les microprocesseurs classiques CISC (Complex Instruction Set Computer), le nombre
d’instructions reconnues varie entre 75 et 150.
Pour les microprocesseurs RISC (Reduced Instruction Set Computer), le nombre d’instructions
est très réduit (entre 10 et 30 instructions), permettant d’améliorer le temps d’exécution des
programmes.
Une instruction est définie par son code opératoire, valeur numérique binaire difficile à manipuler
par l’être humain. On utilise donc une notation symbolique pour représenter les instructions : les
mnémoniques.
Un programme constitué de mnémoniques est appelé programme en assembleur.
Architecture et Microprocesseur
1
Les instructions peuvent être classées en groupes :
o instructions de transfert de données ;
o instructions arithmétiques ;
o instructions logiques ;
o instructions de branchement ...
Architecture et Microprocesseur
2
Les instructions de transfert
Elles permettent de déplacer des données d’une source vers une destination :
o registre vers mémoire ;
o registre vers registre ;
o mémoire vers registre.
Remarque : le microprocesseur 8086 n’autorise pas les transferts de mémoire vers mémoire, pour ce
faire, il faut passer par un registre intermédiaire.
Syntaxe : MOV destination,source
Remarque : MOV est l’abbréviation du verbe « to move » : déplacer.
Il existe différentes façons de spécifier l’adresse d’une case mémoire dans une instruction : ce sont
les modes d’adressage.
Architecture et Microprocesseur
3
Exemples de modes d’adressage simples :
o mov ax,bx : charge le contenu du registre BX dans le registre AX. Dans ce cas, le transfert se fait de
registre à registre : adressage par registre.
o mov al,12H : charge le registre AL avec la valeur 12H. La donnée est fournie immédiatement avec
l’instruction : adressage immédiat.
o mov bl,[1200H] : transfère le contenu de la case
mémoire d’adresse effective (offset) 1200H vers
le registre BL. L’instruction comporte l’adresse
de la case mémoire où se trouve la donnée :
adressage direct. L’adresse effective représente
l’offset de la case mémoire dans le segment de
données (segment dont l’adresse est contenue
dans le registre DS) : segment par défaut.
Architecture et Microprocesseur
4
On peut
changer
le segment
lors d’un
adressage direct en ajoutant un préfixe de
segment.
Exemple : mov bl,es :[1200H]
On parle alors de forçage de segment.
Remarque : dans le cas de l’adressage immédiat de la mémoire, il faut indiquer le format de la
donnée : octet ou mot (2 octets) car le microprocesseur 8086 peut manipuler des données sur 8 bits
ou 16 bits. Pour cela, on doit utiliser un spécificateur de format :
o mov byte ptr [1100H],65H : transfère la valeur
65H (sur 1 octet) dans la case mémoire d’offset
1100H ;
o mov word ptr [1100H],65H : transfère la valeur
0065H (sur 2 octets) dans les cases mémoire
d’offset 1100H et 1101H.
Architecture et Microprocesseur
5
Modes d’adressage évolués
Adressage basé : l’offset est contenu dans un registre de base BX ou BP (pointeur de base pile).
Exemples :
o 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 Data Segment;
o 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 Stack Segment.
Architecture et Microprocesseur
6
Adressage indexé : 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.
Exemples :
o mov al,[si] : charge le registre AL avec le contenu de la case mémoire dont l’offset est contenu
dans SI.
o mov [di],bx : charge les cases mémoire d’offset DI et DI + 1 avec le contenu du registre BX.
Remarque : une valeur constante peut éventuellement être ajoutée aux registres de base ou d’index
pour obtenir l’offset.
Exemple :
Publicité
mov [si+100H],ax
qui peut aussi s’écrire
mov [si][100H],ax
ou encore
mov 100H[si],ax
Les modes d’adressage basés ou indexés permettent la manipulation de tableaux rangés en
mémoire.
Architecture et Microprocesseur
7
Exemple :
mov si,0
mov word ptr table[si],1234H
mov si,2
mov word ptr table[si],5678H
Dans cet exemple, table représente l’offset du premier élément
du tableau et le registre SI joue le rôle d’indice de tableau.
Adressage basé et indexé : l’offset est obtenu en faisant la somme d’un registre de base, d’un
registre d’index et d’une valeur constante.
Exemple : mov ah,[bx+si+100H]
Ce mode d’adressage permet
l’adressage de structures de données complexes : matrices,
enregistrements, ...
Exemple : 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 colonne dans la
matrice.
Architecture et Microprocesseur
8
Les Instructions Arithmétiques
Les instructions arithmétiques de base sont l’addition, la soustraction, la multiplication et la
division qui incluent diverses variantes.
Addition : ADD opérande1,opérande2
L’opération effectuée est : opérande1 ← opérande1 + opérande2.
Exemples :
o add ah,[1100H] : ajoute le contenu de la case mémoire d’offset 1100H à l’accumulateur AH
(adressage direct).
o add ah,[bx] : ajoute le contenu de la case mémoire pointée par BX à l’accumulateur AH (adressage
basé).
o add byte ptr [1200H],05H : ajoute la valeur 05H au contenu de la case mémoire d’offset 1200H
(adressage immédiat).
Architecture et Microprocesseur
9
Soustraction : SUB opérande1,opérande2
L’opération effectuée est : opérande1 ← opérande1 − opérande2.
Multiplication : MUL opérande où opérande est un registre ou une case mémoire.
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).
Exemples :
o mov al,51
mov bl,32
mul bl
AX = 51* 32
o mov al,43
mov byte ptr [1200H],28 AX=43*28
mul byte ptr [1200H]
o mov ax,4253
o mov ax,1234
mov bx,1689
(DX,AX)=4253*1689
mov word ptr [1200H],5678 (DX,AX)=1234*5678
mul bx
mul word ptr [1200H]
Architecture et Microprocesseur
10
Division : DIV opérande, où opérande est un registre ou une case mémoire.
Cette instruction effectue la division du contenu de AX par un opérande sur 1 octet ou le contenu
de (DX,AX) par un opérande sur 2 octets.
Résultat : si l’opérande est sur 1 octet, alors AL = quotient et AH = reste ;
si l’opérande est sur 2 octets, alors AX = quotient et DX = reste.
Exemples :
o mov ax,35
mov bl,10
AL=3 (quotient) et AH=5 (reste)
div bl
o mov dx,0
mov ax,1234 AX=123 (quotient) et DX=4 (reste)
mov bx,10
div bx
Architecture et Microprocesseur
11
Les instructions logiques
Ce sont des instructions qui permettent de manipuler des données au niveau des bits. Les
opérations logiques de base sont :
ET;
OU;
OU exclusif ;
complément à 1;
complément à 2;
décalages et rotations.
Publicité
Les différents modes d’adressage sont disponibles.
ET logique : AND opérande1,opérande2
L’opération effectuée est : opérande1 ← opérande1 ET opérande2.
Exemple :
Architecture et Microprocesseur
12
Application : masquage de bits pour mettre à « 0 » certains bits dans un mot.
Exemple : masquage des bits 0, 1, 6 et 7 dans un octet :
OU logique : OR opérande1,opérande2
L’opération effectuée est : opérande1 ← opérande1 OU opérande2.
Application : mise à 1 d’un ou plusieurs bits dans un mot.
Exemple : dans le mot 10110001, on veut mettre à « 1 » les bits 1 et 3 sans modifier les autres bits.
Les instructions correspondantes peuvent s’écrire :
mov ah,10110001B
or ah,00001010B
Architecture et Microprocesseur
13
Complément à 1 : NOT opérande
L’opération effectuée est :
Exemple :
Complément à 2 : NEG opérande
L’opération effectuée est :
Exemple :
OU exclusif : XOR opérande1,opérande2
L’opération effectuée est : opérande1 ← opérande1 ⊕opérande2.
Exemple : mise à zéro d’un registre :
Architecture et Microprocesseur
14
Instructions de décalages et de rotations : 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).
Dans les rotations, les bits déplacés dans un sens sont réinjectés de l’autre coté du mot.
Décalage logique vers la droite (Shift Right) : SHR opérande,n
Cette instruction décale l’opérande de n positions vers la droite.
Exemple :
entrée d’un 0 à la place du bit de poids fort ; le bit sortant passe à travers l’indicateur de retenue
CF.
Architecture et Microprocesseur
15
Remarque : si le nombre de bits à décaler est supérieur à 1, ce nombre doit être placé dans le
registre CL ou CX.
Exemple : décalage de AL de trois positions vers la droite :
Décalage logique vers la gauche (Shift Left) : SHL opérande,n
Cette instruction décale l’opérande de n positions vers la droite.
Exemple :
entrée d’un 0 à la place du bit de poids faible; le bit sortant passe à travers l’indicateur de
retenue CF.
Même remarque que précédemment si le nombre de positions à décaler est supérieur à 1.
Architecture et Microprocesseur
16
Décalage arithmétique vers la droite : SAR opérande,n
Ce décalage conserve le bit de signe bien que celui-ci soit décalé.
Exemple :
le bit de signe est réinjecté.
Décalage arithmétique vers la gauche : SAR opérande,n
Identique au décalage logique vers la gauche.
Applications des instructions de décalage :
o Cadrage à droite d’un groupe de bits
Exemple : on veut avoir la valeur du quartet de poids fort du registre AL :
Architecture et Microprocesseur
17
o Test de l’état d’un bit dans un mot
Exemple : on veut déterminer l’état du bit 5 de AL :
avec un décalage de 6 positions vers la droite ou 3 positions vers la gauche, le bit 5 de AL est
transféré dans l’indicateur de retenue CF. Il suffit donc de tester cet indicateur.
o Multiplication ou division par une puissance de 2
un décalage à droite revient à faire une division par 2 et un décalage à gauche, une multiplication
par 2.
Exemple :
Rotation à droite (Rotate Right) : ROR opérande,n
Cette instruction décale l’opérande de n positions vers la droite et réinjecte par la gauche les bits
sortant.
Architecture et Microprocesseur
18
Exemple :
réinjection du bit sortant qui est
copié dans l’indicateur de retenue
CF.
Rotation à gauche (Rotate Left) : ROL opérande,n
Cette instruction décale l’opérande de n positions vers la gauche et réinjecte par la droite les bits
sortant.
Exemple :
réinjection du bit sortant qui est
copié dans l’indicateur de retenue
CF.
Rotation à droite avec passage par l’indicateur de retenue (Rotate Right through Carry) :
RCR opérande,n
Cette instruction décale l’opérande de n positions vers la droite en passant par l’indicateur de
retenue CF.
Architecture et Microprocesseur
Publicité
19
Exemple :
le bit sortant par la droite est
copié
dans
l’indicateur
de
retenue
CF
et
la
valeur
précédente de CF est réinjectée
par la gauche.
Rotation à gauche avec passage par l’indicateur de retenue (Rotate Left through Carry) :
RCL opérande,n
Cette instruction décale l’opérande de n positions vers la gauche en passant par l’indicateur de
retenue CF.
Exemple :
le bit sortant par la gauche
est copié dans l’indicateur de
retenue CF
et
la
valeur
précédente de CF est réinjectée
par la droite.
Architecture et Microprocesseur
20
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 : JMP label
Cette instruction effectue un saut (jump) vers le label spécifié. Un label ou étiquette est une
représentation symbolique d’une instruction en mémoire :
Architecture et Microprocesseur
21
Remarque : l’instruction JMP ajoute au registre IP (pointeur d’instruction) le nombre d’octets
(distance) qui sépare l’instruction de saut de sa destination. Pour un saut en arrière, la distance est
négative (codée en complément à 2).
Instructions de sauts conditionnels : Jcondition label
Un saut conditionnel n’est exécuté que si une certaine condition est satisfaite, sinon l’exécution se
poursuit séquentiellement à l’instruction suivante.
La condition du saut porte sur l’état de l’un des indicateurs d’état du microprocesseur :
CF : indicateur de retenue (carry) ;
PF : indicateur de parité;
ZF : indicateur de zéro ;
SF : indicateur de signe ;
OF : indicateur de dépassement
(overflow).
Architecture et Microprocesseur
22
Remarque : les indicateurs sont positionnés en fonction du résultat de la dernière opération.
Exemple :
Remarque : il existe un autre type de saut conditionnel, les sauts arithmétiques. Ils suivent en
général l’instruction de comparaison : CMP opérande1,opérande2
Architecture et Microprocesseur
23
Exemple d’application des instructions de sauts conditionnels : on veut additionner deux nombres
signés N1 et N2 se trouvant respectivement aux offsets 1100H et 1101H. Le résultat est rangé à
l’offset 1102H s’il est positif, à l’offset 1103H s’il est négatif et à l’offset 1104H s’il est nul.
Architecture et Microprocesseur
24
Appel de sous-programme
Pour éviter la répétition d’une même séquence d’instructions plusieurs fois dans un programme,
on rédige la séquence une seule fois en lui attribuant un nom et on l’appelle lorsqu’on en a besoin.
Le programme appelant est le programme principal. La séquence appelée est un sous-programme ou
procédure.
Ecriture d’un sous-programme :
Remarque : une procédure peut être de type NEAR si elle se trouve dans le même segment ou de
type FAR si elle se trouve dans un autre segment.
Exemple :
Appel d’un sous-programme par le programme principal : CALL procédure
Architecture et Microprocesseur
25
Lors de l’exécution de l’instruction CALL, le
pointeur d’instruction IP est
chargé avec
l’adresse de la première instruction du sous-
programme. Lors du retour au programme
appelant, l’instruction suivant le CALL doit
être exécutée, càd que IP doit être rechargé
avec l’adresse de cette instruction.
Avant de charger IP avec l’adresse du sous-programme, l’adresse de retour au programme
principal, càd le contenu de IP, est sauvegardée dans une zone mémoire particulière appelée pile.
Lors de l’exécution de l’instruction RET, cette adresse est récupérée à partir de la pile et rechargée
dans IP, ainsi le programme appelant peut se poursuivre.
Architecture et Microprocesseur
Publicité
26
Fonctionnement de la pile : la pile est une zone mémoire fonctionnant en mode LIFO (Last In
First Out : dernier entré, premier sorti). Deux opérations sont possibles sur la pile :
o empiler une donnée : placer la donnée au sommet de la pile ;
o dépiler une donnée : lire la donnée se trouvant au sommet de la pile.
Le sommet de la pile est repéré par un registre appelé pointeur de pile (SP : Stack Pointer) qui contient
l’adresse de la dernière donnée empilée. La pile est définie dans le segment de pile dont l’adresse
de départ est contenue dans le registre SS (Stack Segment, registre de segment de pile).
Architecture et Microprocesseur
27
La pile et le programme croissent en sens inverse pour diminuer le risque de collision entre le code
et la pile dans le cas où celle-ci est placée dans le même segment que le code (SS = CS).
Lors de l’appel à un sous-programme, l’adresse de retour au programme appelant (contenu de IP)
est empilée et le pointeur de pile SP est automatiquement décrémenté. Au retour du sous-
programme, le pointeur d’instruction IP est rechargé avec la valeur contenue sommet de la pile et
SP est incrémenté.
Architecture et Microprocesseur
28
La pile peut également servir à sauvegarder le contenu de registres qui ne sont pas
automatiquement sauvegardés lors de l’appel à un sous programme :
o instruction d’empilage : PUSH opérande
o instruction de dépilage : POP opérande
où opérande est un registre ou une donnée sur 2 octets (on ne peut empiler que des mots de 16
bits).
Exemple :
Remarque : la valeur du pointeur de pile (SP) doit être initialisée par le programme principal avant
de pouvoir utiliser la pile.
Utilisation de la pile pour le passage de paramètres : pour transmettre des paramètres à une procédure,
on peut les placer sur la pile avant l’appel de la procédure, puis celle-ci les récupère en effectuant
un adressage basé de la pile en utilisant le registre BP.
Architecture et Microprocesseur
29
Exemple : Ecrire une procédure effectuant la somme de deux nombres et retournant le résultat dans
le registre AX .
Programme principal :
Procédure somme :
Architecture et Microprocesseur
30
L’instruction ret 4 permet de retourner au programme principal et d’incrémenter le pointeur de pile
de 4 unités pour dépiler les paramètres afin de remettre la pile dans son
état initial.
Etat de la pile :
Architecture et Microprocesseur
31
Méthodes de programmation
Etapes de la réalisation d’un programme
o Définir le problème à résoudre : que faut-il faire exactement ?
o Déterminer des algorithmes, des organigrammes : comment faire? Par quoi commencer,
puis poursuivre ?
o Rédiger le programme (code source) :
utilisation du jeu d’instructions (mnémoniques) ;
création de documents explicatifs (documentation).
o Tester le programme en réel ;
o Corriger les erreurs (bugs) éventuelles : déboguer le programme puis refaire des tests jusqu’à
obtention d’un programme fonctionnant de manière satisfaisante.
Langage machine et assembleur
o Langage machine : codes binaires correspondant aux instructions ;
o Assembleur
:
logiciel de traduction du code source écrit en langage assembleur
(mnémoniques).
Architecture et Microprocesseur
32
Réalisation pratique d’un programme :
o Rédaction du code source en assembleur à l’aide d’un éditeur (logiciel de traitement de texte
ASCII) :
edit sous MS-DOS,
notepad (bloc-note) sous Windows,
o Assemblage du code source (traduction des instructions en codes binaires) avec un
assembleur :
MASM de Microsoft,
TASM de Borland,
A86 disponible en shareware sur Internet, ...
pour obtenir le code objet : code machine exécutable par le microprocesseur ;
o Chargement en mémoire centrale et exécution : rôle du système d’exploitation ou d’un
moniteur (carte de développement à base de microprocesseur).
Pour la mise au point (débogage) du programme, on peut utiliser un programme d’aide
Architecture et Microprocesseur
33
Structure d’un fichier source en assembleur :
Pour faciliter la lisibilité du code source en assembleur, on le rédige sous la forme suivante :
Directives pour l’assembleur :
o Origine du programme en mémoire : ORG offset
o Définitions de constantes : nom constante EQU valeur
o Réservation de cases mémoires :
nom variable DB valeur initiale DB : Define Byte (réservation d’un octet)
nom variable DW valeur initiale DW : Define Word (réservation d’un mot : 2 octets)
Exemples :
Architecture et Microprocesseur
34