La programmation en assembleur du microprocesseur 8086

Page 1 sur 35Lecteur de document UniversityLib

La programmation en assembleur du microprocesseur 8086

Computer Science - Microprocessor Architecture and Assembly Language · notes

Voir tous les documents en programmation

CHAPITRE V

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.

Cours Architecture & µprocesseur

1

Les instructions peuvent etre classées en groupes :

Ø instructions de transfert de données ;

Ø instructions arithmétiques ;

Ø instructions logiques ;

Ø instructions de branchement ...

Cours Architecture & µprocesseur

2

Les instructions de transfert

Elles permettent de déplacer des données d’une source vers une

destination :

Ø registre vers mémoire ;

Ø registre vers registre ;

Ø 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.

Cours Architecture & µprocesseur

3

Exemples de modes d’adressage simples :

Ø 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.

Ø mov al,12H : charge le registre AL avec la valeur 12H. La donnée est fournie

immédiatement avec l’instruction : adressage immédiat.

le

Ø mov bl,[1200H] : transfère le contenu de

la case mémoire d’adresse effective

registre BL.

(offset) 1200H vers

L’instruction comporte l’adresse de la case

:

mémoire où se trouve

adressage direct. L’adresse effective

représente l’offset de la case mémoire

dans le segment de données (segment

dont

le

registre DS) : segment par défaut.

l’adresse est contenue dans

la donnée

Cours Architecture & µprocesseur

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

segment.

forçage de

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 :

Ø mov byte ptr [1100H],65H : transfère la

valeur 65H (sur 1 octet) dans la case

mémoire d’offset 1100H ;

Ø mov word ptr [1100H],65H : transfère la

valeur 0065H (sur 2 octets) dans les

cases mémoire d’offset 1100H et 1101H.

Cours Architecture & µprocesseur

5

Modes d’adressage évolués

adressage basé : l’offset est contenu dans un registre de base BX ou BP.

Exemples :

Ø mov al,[bx] : transfère la donnée dont l’offset est contenu dans le registre

de base BX vers le registre AL. Le segment associé par défaut au registre BX

est le segment de données : on dit que l’adressage est basé sur DS;

Ø mov al,[bp] : le segment par défaut associé au registre de base BP est le

segment de pile. Dans ce cas, l’adressage est basé sur SS.

Cours Architecture & µprocesseur

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 :

Ø mov al,[si] : charge le registre AL avec le contenu de la case mémoire dont

l’offset est contenu dans SI.

Ø mov [di],bx : charge les cases mémoire d’offset DI et DI + 1 avec le contenu

Publicité

du registre BX.

Remarque : une valeur constante peut éventuellement être ajoutée aux

registres de base

ou d’index pour obtenir l’offset.

Exemple :

mov [si+100H],ax qui peut aussi s’écrire mov [si][100H],ax

ou encore mov 100H[si],ax

Cours Architecture & µprocesseur

7

Les modes d’adressage basés ou indexés permettent la manipulation de tableaux

rangés en mémoire.

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.

Cours Architecture & µprocesseur

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 :

Ø add ah,[1100H] : ajoute le contenu de la case mémoire d’offset 1100H à

l’accumulateur

AH (adressage direct).

Ø add ah,[bx] : ajoute le contenu de la case mémoire pointée par BX à l’accumulateur

AH (adressage basé).

Ø add byte ptr [1200H],05H : ajoute la valeur 05H au contenu de la case mémoire

d’offset 1200H (adressage immédiat).

Cours Architecture & µprocesseur

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 :

Ø mov al,51

mov bl,32 AX = 51* 32

mul bl

Ø mov ax,4253

mov bx,1689

mul bx

(DX,AX)=4253*1689

Ø mov al,43

mov byte ptr [1200H],28

mul byte ptr [1200H]

AX=43*28

Cours Architecture & µprocesseur

10

Ø mov ax,1234

mov word ptr [1200H],5678 (DX,AX)=1234*5678

mul word ptr [1200H]

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 :

Ø mov ax,35

mov bl,10 AL=3 (quotient) et AH=5 (reste)

div bl

Ø mov dx,0

mov ax,1234 AX=123 (quotient) et DX=4 (reste)

mov bx,10

div bx

Cours Architecture & µprocesseur

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;

Publicité

Ø décalages et rotations.

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 :

Cours Architecture & µprocesseur

13

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

Cours Architecture & µprocesseur

14

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 :

Cours Architecture & µprocesseur

15

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.

Cours Architecture & µprocesseur

16

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.

Cours Architecture & µprocesseur

17

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 :

Ø Cadrage à droite d’un groupe de bits

Exemple : on veut avoir la valeur du quartet de poids fort du registre AL :

Cours Architecture & µprocesseur

18

Ø 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 4 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.

Ø 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.

Exemple :

 réinjection du bit sortant qui est copié

dans l’indicateur de retenue CF.

Cours Architecture & µprocesseur

19

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.

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.

Publicité

Cours Architecture & µprocesseur

20

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.

Cours Architecture & µprocesseur

21

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 :

Cours Architecture & µprocesseur

22

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

:

(overflow).

indicateur de dépassement

Cours Architecture & µprocesseur

23

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

Cours Architecture & µprocesseur

24

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.

Cours Architecture & µprocesseur

25

Appel de sous-programmes : 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

Cours Architecture & µprocesseur

26

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.

Cours Architecture & µprocesseur

27

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 :

Ø

Ø

empiler une donnée : placer la donnée au sommet de la pile ;

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).

Cours Architecture & µprocesseur

28

Remarque : 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

Publicité

(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é.

Cours Architecture & µprocesseur

29

La pile peut également servir à sauvegarder le contenu de registres qui ne sont pas

automatiquement sauvegardés lors de l’appel à un sous programme :

Ø

Ø

instruction d’empilage : PUSH opérande

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.

Cours Architecture & µprocesseur

30

Exemple : soit une procédure effectuant la somme de deux nombres et

retournant le résultat dans le registre AX .

Ø programme principal :

Ø procédure somme :

Cours Architecture & µprocesseur

31

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 :

Cours Architecture & µprocesseur

32

Méthodes de programmation

Etapes de la réalisation d’un programme :

Ø Définir le problème à résoudre : que faut-il faire exactement ?

Ø Déterminer des algorithmes, des organigrammes : comment faire?

Par quoi commencer, puis poursuivre ?

Ø Rédiger le programme (code source) :

utilisation du jeu d’instructions (mnémoniques) ;

création de documents explicatifs (documentation).

Ø Tester le programme en réel ;

Ø 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 :

Ø Langage machine : codes binaires correspondant aux instructions ;

Ø Assembleur : logiciel de traduction du code source écrit en langage

assembleur (mnémoniques).

Cours Architecture & µprocesseur

33

Réalisation pratique d’un programme :

Ø

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,

Ø

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 ;

Ø

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

À la mise au point (comme DEBUG sous MS-DOS) permettant :

l’exécution pas à pas;

la visualisation du contenu des registres et de la mémoire ;

la pose de points d’arret …

Cours Architecture & µprocesseur

34

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 :

Ø

Origine du programme en mémoire : ORG offset

Exemple : org 1000H

Ø

Définitions de constantes : nom constante EQU valeur

Exemple : escape equ 1BH

Ø

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 :

Cours Architecture & µprocesseur

35