programmation en assembleur 8086 pdf february 10 2009-5-39 pm 170k

17
Microprocesseur 8086 - TD 4 TD 4 : Programmation en assembleur 8086 Exercice 1 : Ecrire un programme, en langage assembleur 8086, qui permet de compter les nombres nuls dans un tableau d’octets mémoire de longueur 100h et débutant à l’adresse [200h], le résultat sera placé à l’adresse [400h]. Solution : Exploitation des registres : Le compteur C sera remplacé par le registre CX, et comme tout le tableau de N octets sera examiné, donc CX va prendre N valeurs, la toute dernière est toujours égale à 1, donc la valeur initiale sera N : CX = N, N-1, N-2, ... 2, 1. Lorsque CX est initialisé à N, La valeur actuelle du tableau mémoire, qui est définie par DS:[SI], est initialisée par DS:[100h] ; à chaque décrémentation de CX correspond une incrémentation de SI. Début NZ <-- 0 C <-- 1 T(C) = 0 ? NZ <-- NZ + 1 C <-- C + 1 C < N ? Fin OUI NON OUI NON 1

Upload: soufiane-mellahi

Post on 19-Jan-2016

15 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Microprocesseur 8086 - TD 4

TD 4 : Programmation en assembleur 8086

Exercice 1 :

Ecrire un programme, en langage assembleur 8086, qui permet de compter les nombres nuls

dans un tableau d’octets mémoire de longueur 100h et débutant à l’adresse [200h], le résultat

sera placé à l’adresse [400h].

Solution :

Exploitation des registres :

Le compteur C sera remplacé par le registre CX, et comme tout le tableau de N octets sera

examiné, donc CX va prendre N valeurs, la toute dernière est toujours égale à 1, donc la

valeur initiale sera N :

CX = N, N-1, N-2, ... 2, 1.

Lorsque CX est initialisé à N, La valeur actuelle du tableau mémoire, qui est définie par

DS:[SI], est initialisée par DS:[100h] ; à chaque décrémentation de CX correspond une

incrémentation de SI.

Début

NZ <-- 0 C <-- 1

T(C) = 0 ?

NZ <-- NZ + 1

C <-- C + 1

C < N ?

Fin

OUI NON

OUI NON

1

Page 2: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Après la décrémentation de CX, on n’a pas besoin d’effectuer une comparaison entre CX et 0,

parce que la décrémentation est suffisante pour affecter le flag Z dont on a besoin pour

effectuer l’instruction de saut qui vient juste après la décrémentation de CX.

Donc les instructions de saut sont généralement utilisées après une comparaison ou après une

décrémentation du compteur.

Début

BX <-- 0h CX <-- 100h SI <-- 200h

Z = 1 ?

BX <-- BX + 1

SI <-- SI + 1 CX <-- CX - 1

Z = 1 ?

Fin

NON OUI

OUI NON

CMP DS:[SI],0

DS:[400h] <-- BX

2

Page 3: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Le programme en langage assembleur 8086 : (partie la plus significative)

MOV CX, 100h MOV BX, 0000h MOV SI, 200h

Etq2 : CMP [SI], 0 JNZ Etq1 INC BX

Etq1 : INC SI DEC CX JNZ Etq2 MOV [400], BX BRK

Contrairement à l’instruction HLT qui fait arrêter le 8086 de toute activité jusqu’à l’arrivée

d’une interruption matérielle, l’instruction BRK (break) fait arrêter le programme en cours

d’exécution et revenir à l’exécution du système d’exploitation.

3

Page 4: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Exercice 2 :

Ecrire un programme qui permet de déterminer le maximum dans un tableau d’octets

mémoire de longueur 100h et débutant à l’adresse [200h], le résultat sera placé à l’adresse

[400h].

Solution :

Début

CX <-- FFh SI <-- 200h

AL <-- [SI]

CX <-- CX - 1

Z = 1 ?

Fin

NON OUI

NON OUI

AL <-- [SI]

DS:[400h] <-- AL

AL > [SI] ?

SI <-- SI + 1

4

Page 5: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Le compteur CX a été initialisé à : N-1 = 100h - 1 = FFh ; En fait le registre AL prend la

première valeur du tableau, c à d [200h] ; Puis il est comparé avec les N-1 valeurs suivantes.

Pour chaque comparaison, CX prend une valeur, pour la comparaison de la dernière valeur du

tableau, la valeur de CX et égale à 1, donc la valeur initiale de CX est N-1 :

CX = N-1, N-2, ... 2, 1.

Le programme en langage assembleur 8086 : (partie la plus significative)

MOV CX, FFh MOV SI, 200h MOV AL, [SI]

Etq2 : INC SI CMP AL, [SI] JLE Etq1 MOV AL, [SI]

Etq1 : DEC CX JNZ Etq2 MOV [400], AL BRK

5

Page 6: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Exercice 3 :

Ecrire un programme qui permet de trier par ordre croissant un tableau de longueur N = 100h

débutant à l’adresse [200h].

Solution :

Début

BX <-- 200h CX <-- N-1

XCHG AL,[SI] [BX] <-- AL

SI <-- SI + 1 DX <-- DX - 1

Z = 1 ?

Fin

NON OUI

OUI NON

SI <-- BX + 1 DX <-- CX

AL > [SI] ?

AL <-- [BX]

BX <-- BX + 1 CX <-- CX - 1

OUI

Z = 1 ?

NON

6

Page 7: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Dans cette solution on a eu besoin de deux compteurs CX et DX ; En fait, pour chaque valeur

du compteur CX on prend une des (N - 1) premières valeurs du tableau et on la compare avec

toutes les valeurs qui viennent après (avec une pour chaque valeur de DX). Le compteur CX

prend donc les valeurs suivantes :

CX = N-1, N-2, ... 2, 1.

Lorsque CX est fixé à une valeur (i), on est alors entrain de comparer la valeur (N - i) du

tableau avec les (i) valeurs qui viennent après ; Donc pour chaque valeur de CX, DX prendra

les valeurs suivantes :

DX = CX-1, CX-2, ... 2, 1.

7

Page 8: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Une deuxième solution :

Début

CX <-- N-1

XCHG AL,[SI+1] [SI] <-- AL BL <-- BL+1

SI <-- SI + 1 DX <-- DX - 1

Fin

NON OUI

NON OUI AL ≤ [SI+1] ?

AL <-- [SI]

OUI

NON

SI <-- 200h DX <-- CX BL <-- 0

BL = 0 ?

Z = 1 ?

CX <-- CX - 1

NON

Z = 1 ?

OUI

8

Page 9: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Dans cette solution on fait le tri de chaque deux valeurs successives du tableau (si elles ne

sont pas triées entre elles dans l’ordre croissant, on fait une permutation entre elles) ;

Pour chaque valeur du compteur secondaire DX, les valeurs à trier sont pointées par [SI] et

[SI+1] ;

Le tableau ayant N valeurs, et le premier passage se faisant jusqu’à comparer entre l’avant

dernière et la dernière valeur, le compteur principal CX aura donc à parcourir (N - 1) valeurs,

c à d :

CX = N-1, N-2, ... 2, 1

Cette solution permet d’arrêter le processus lorsqu’on constate que le tableau et déjà trié après

un passage du compteur secondaire DX par toutes ses valeurs concernées, même avant

d’atteindre la limite du compteur principal (CX = 1) ;

Pour chaque passage (i) (c à d pour chaque valeur du compteur principal CX = N - i), SI varie

de sa valeur initiale (200h) jusqu’à la valeur (200h + N - i -1), ce qui donne (N - i) valeurs,

donc le compteur DX va prendre les (N - i) valeurs suivantes :

DX = N-i, N-i-1, N-i-2, ... 2, 1

Ce qui donne :

DX = CX, CX-1, CX-2, ... 2, 1

Par exemple, pour un tableau de longueur N = 5, et pour le premier passage et le deuxième

passage (i = 1) on aura :

CX = 3

DX = 3 2 1

(SI+1) finale

CX = 4

DX = 4 3 2 1

(SI+1) finale

9

Page 10: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Le programme en langage assembleur 8086 :

;tri3 CODE START : BEGIN : Etq3 : Etq2 : Etq1 : Fin : CODE

SEGMENT ASSUME CS:CODE, DS:CODE ES:CODE ORG 0100H N EQU 100H JMP BEGIN ; la procédure sera placée ici MOV AX, CODE MOV DS, AX MOV ES, AX MOV CX, N-1 MOV SI, 200h MOV DX, CX MOV BL, 0 MOV AL, [SI] CMP AL, [SI+1] JLE Etq1 XCHG AL, [SI+1] MOV [SI], AL INC BL INC SI DEC DX JNZ Etq2 CMP BL, 0 JZ Fin DEC CX JNZ Etq3 BRK ENDS END START

10

Page 11: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Une troisième solution : (utilisation d’un sous-programme appelé ‘FINDMAX’)

Début

CX <-- N-1

Fin

OUI

NON

BL = 0 ?

CX <-- CX - 1

NON

Z = 1 ? OUI

FINDMAX

11

Page 12: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Le sous-programme :

XCHG AL,[SI+1] [SI] <-- AL BL <-- BL+1

SI <-- SI + 1 DX <-- DX - 1

NON OUI

NON OUI AL ≤ [SI+1] ?

AL <-- [SI]

SI <-- 200h DX <-- CX BL <-- 0

Z = 1 ?

RET

12

Page 13: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Le programme en langage assembleur 8086 :

programme sous-programme

;tri3 CODE START : BEGIN : Etq3 : Fin : CODE

SEGMENT ASSUME CS:CODE, DS:CODE ES:CODE ORG 0100H N EQU 100H JMP BEGIN ; la procédure sera placée ici MOV AX, CODE MOV DS, AX MOV ES, AX MOV CX, N-1 CALL FINDMAX CMP BL, 0 JZ Fin DEC CX LOOP Etq3 BRK ENDS END START

FINDMAX Etq2: Etq1 : FINDMAX

PROC PUSH CX MOV SI, 200h MOV DX, CX MOV BL, 0 MOV AL, [SI] CMP AL, [SI+1] JLE Etq1 XCHG AL, [SI+1] MOV [SI], AL INC BL INC SI DEC DX JNZ Etq2 POP CX RET ENDP

Remarques :

Le compteur CX est utilisé par le programme principal, mais il n’est pas nécessaire de l’empiler avant

l’exécution de la procédure du sous-programme, car cette dernière ne modifie pas le contenu de CX.

Il est possible aussi de faire l’empilement de CX dans le programme principal juste avant le CALL et de faire

son désempilement dans le programme principal aussi juste après le CALL.

Le registre BL ne peut pas être empilé et désempilé par le programme principal, car la valeur retournée par le

sous-programme ne doit pas être perdue avant son utilisation dans l’instruction (CMP BL, 0) qui vient après le

sous programme.

On rappelle que pour un programme dont l’ensemble des segments ne dépasse pas les 64 Ko,

alors, le programme est organisé selon le canevas suivant :

; nom du programme

CODE START : BEGIN : CODE

SEGMENT ASSUME CS:CODE, DS:CODE ES:CODE, SS:CODE ORG 0100H placer toutes les ‘EQU’ ici JMP BEGIN placer tous les ‘define’ ici placer toutes les procédures ici placer votre programme ici ENDS END START

13

Page 14: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Exercice 4 :

Ecrire un programme qui puisse calculer le PGDC (plus grand diviseur commun) de deux

nombres se trouvant aux adresses [200h] et [201h] ; le résultat sera placé à l’adresse [202h].

On rappelle que :

* PGDC [n , m] = PGDC [m , reste(n/m)] , n > m

* PGDC [n , 0] = n , quelque soit n

Solution :

Cette solution utilise une procédure récursive (qui fait appel à elle-même) :

programme sous-programme

;pgdcom CODE START : BEGIN : CODE

SEGMENT ASSUME CS:CODE, DS:CODE ES:CODE ORG 0100H JMP BEGIN ; la procédure sera placée ici MOV AL, [200] MOV BL, [201] CBW ; forcer AH = 0 CALL PGDC MOV [202], AL BRK ENDS END START

PGDC FIN : PGDC

PROC PUSH AX PUXH BX DIV BL CMP AH, 00H JZ FIN MOV AL, BL MOV BL, AH CBW CALL PGDC POP BX POP AX RET ENDP

Remarque :

Les registres AH, AL, BH, BL sont employés par le programme principal et par la procédure, donc on doit les

empiler avant de les utiliser par la procédure, puis les désempiler après finir leur utilisation avec la procédure

(PUSH et POP ne fonctionnent que sur des registres 16 bits).

14

Page 15: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Exercice 5 :

Ecrire un programme qui puisse calculer à un dixième près la moyenne arithmétique de

N = 100 valeurs se trouvant dans un tableau.

Solution :

;moy CODE START : BEGIN : Boucle : Fin : CODE

SEGMENT ASSUME CS:CODE, DS:CODE ES:CODE ORG 0100H N EQU 100D JMP BEGIN MOV AX, CODE MOV DS, AX MOV ES, AX MOV SI, 200 MOV CL, N MOV BX, N MOV AX, 0000H ADD AX, [SI] INC SI LOOP Boucle CWD ; Forcer DX = 0 DIV BX XCHG AX, BX MOV [0400H], 0AH ; 0A Hexa = 10 Déci MUL [0100H] DIV BL BRK ENDS END START

15

Page 16: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

Exercice 6 :

Ecrire un programme qui indique la présence de la chaîne de caractères ‘TEC568’ qui débute

à l’adresse [300h], dans un tableau de N = 96 éléments qui débute à l’adresse [200h], (utiliser

deux procédures ‘AFICH_OK’ et ‘AFFICH_NK’ pour afficher le résultat).

Solution :

Début

SI <-- 200h CX <-- N-5

DEC BL

AFFICH_OK

Fin

NON

OUI

OUI NON Z = 1 ?

CMPSB

OUI

DI <-- 300h BL <-- 6 CLD

Z = 1 ?

Z = 1 ?

NON

OUI BL = 5 ?

NON

DEC SI

AFFICH_NK

DEC CX

16

Page 17: Programmation en Assembleur 8086 PDF February 10 2009-5-39 Pm 170k

La longueur de la chaîne ‘TEC586’ est N’ = 6, la première lettre ‘T’ est donc cherchée parmi

les (N - N’ -1) premières valeurs ; et le compteur CX prend les valeurs suivantes (sa dernière

valeur est toujours égales à 1) :

CX = N - (N’ - 1), N - (N’ - 1) - 1, ... 2, 1

Par exemple, si N = 15, on aura :

Le programme :

;moy CODE START : BEGIN : Etq1 : Etq2 : Etq3 Etq4 Fin : CODE

SEGMENT ASSUME CS:CODE, DS:CODE ES:CODE ORG 0100H N EQU 96D JMP BEGIN MOV AX, CODE MOV DS, AX MOV ES, AX MOV SI, 0200H MOV CX, N-5 MOV DI, 0300H MOV BL, 6 CLD CMPSB JNZ Etq3 DEC BL JNZ Etq2 CALL AFFICH_OK JMP FIN CMP BL, 5 JZ Etq4 DEC SI LOOP Etq1 CALL AFFICH_NK INT 3 ENDS END START

Rev 1.06 (25 - 01 - 2009) - http://www.electro.bbactif.com/ - Code is Poetry

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

T E C 5 8 6

CX = 10 9 8 7 6 5 4 3 2 1

17