Vous êtes sur la page 1sur 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 doctets mmoire de longueur 100h et dbutant ladresse [200h], le rsultat sera plac ladresse [400h]. Solution :

Dbut

NZ <-- 0 C <-- 1

NON

T(C) = 0 ?

OUI

NZ <-- NZ + 1

C <-- C + 1

NON C < N ?

OUI

Fin

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 dernire 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 mmoire, qui est dfinie par DS:[SI], est initialise par DS:[100h] ; chaque dcrmentation de CX correspond une incrmentation de SI. 1

Dbut

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

CMP DS:[SI],0

NON

Z = 1 ?

OUI

BX <-- BX + 1

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

OUI Z = 1 ?

NON

DS:[400h] <-- BX

Fin

Aprs la dcrmentation de CX, on na pas besoin deffectuer une comparaison entre CX et 0, parce que la dcrmentation est suffisante pour affecter le flag Z dont on a besoin pour effectuer linstruction de saut qui vient juste aprs la dcrmentation de CX. Donc les instructions de saut sont gnralement utilises aprs une comparaison ou aprs une dcrmentation du compteur.

Le programme en langage assembleur 8086 : (partie la plus significative) MOV MOV MOV CMP JNZ INC INC DEC JNZ MOV BRK CX, 100h BX, 0000h SI, 200h [SI], 0 Etq1 BX SI CX Etq2 [400], BX

Etq2 : Etq1 :

Contrairement linstruction HLT qui fait arrter le 8086 de toute activit jusqu larrive dune interruption matrielle, linstruction BRK (break) fait arrter le programme en cours dexcution et revenir lexcution du systme dexploitation.

Exercice 2 : Ecrire un programme qui permet de dterminer le maximum dans un tableau doctets mmoire de longueur 100h et dbutant ladresse [200h], le rsultat sera plac ladresse [400h]. Solution :

Dbut

CX <-- FFh SI <-- 200h

AL <-- [SI]

SI <-- SI + 1

OUI AL > [SI] ?

NON

AL <-- [SI]

CX <-- CX - 1

OUI Z = 1 ?

NON

DS:[400h] <-- AL

Fin

Le compteur CX a t initialis : N-1 = 100h - 1 = FFh ; En fait le registre AL prend la premire 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 dernire 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 MOV MOV INC CMP JLE MOV DEC JNZ MOV BRK CX, FFh SI, 200h AL, [SI] SI AL, [SI] Etq1 AL, [SI] CX Etq2 [400], AL

Etq2 :

Etq1 :

Exercice 3 : Ecrire un programme qui permet de trier par ordre croissant un tableau de longueur N = 100h dbutant ladresse [200h]. Solution : Dbut

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

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

AL <-- [BX]

NON

OUI AL > [SI] ?

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

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

OUI Z = 1 ?

NON

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

NON Z = 1 ?

OUI

Fin 6

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) premires valeurs du tableau et on la compare avec toutes les valeurs qui viennent aprs (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 aprs ; Donc pour chaque valeur de CX, DX prendra les valeurs suivantes : DX = CX-1, CX-2, ... 2, 1.

Une deuxime solution : Dbut

CX <-- N-1

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

AL <-- [SI]

OUI AL [SI+1] ?

NON

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

SI <-- SI + 1 DX <-- DX - 1 OUI NON

Z = 1 ?

NON BL = 0 ? OUI

CX <-- CX - 1

Z = 1 ? NON OUI Fin 8

Dans cette solution on fait le tri de chaque deux valeurs successives du tableau (si elles ne sont pas tries entre elles dans lordre croissant, on fait une permutation entre elles) ; Pour chaque valeur du compteur secondaire DX, les valeurs trier sont pointes par [SI] et [SI+1] ; Le tableau ayant N valeurs, et le premier passage se faisant jusqu comparer entre lavant dernire et la dernire valeur, le compteur principal CX aura donc parcourir (N - 1) valeurs, cd: CX = N-1, N-2, ... 2, 1 Cette solution permet darrter le processus lorsquon constate que le tableau et dj tri aprs un passage du compteur secondaire DX par toutes ses valeurs concernes, mme avant datteindre 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 deuxime passage (i = 1) on aura : CX = 4 CX = 3

DX = 4

DX = 3

1 (SI+1) finale

(SI+1) finale

Le programme en langage assembleur 8086 :


;tri3 CODE SEGMENT ASSUME ORG JMP

START :

CS:CODE, DS:CODE ES:CODE 0100H N EQU 100H BEGIN

; la procdure sera place ici BEGIN : MOV AX, CODE MOV DS, AX MOV ES, AX MOV CX, N-1 Etq3 : 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

Etq2 :

Etq1 :

Fin : CODE

10

Une troisime solution : (utilisation dun sous-programme appel FINDMAX)

Dbut

CX <-- N-1

FINDMAX

NON BL = 0 ?

OUI

CX <-- CX - 1

NON Z = 1 ?

OUI

Fin

11

Le sous-programme :

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

AL <-- [SI] OUI AL [SI+1] ? XCHG AL,[SI+1] [SI] <-- AL BL <-- BL+1 NON

SI <-- SI + 1 DX <-- DX - 1 OUI Z = 1 ? RET NON

12

Le programme en langage assembleur 8086 : programme


;tri3 CODE

sous-programme
FINDMAX SEGMENT ASSUME ORG JMP CS:CODE, DS:CODE ES:CODE 0100H N EQU 100H BEGIN Etq2: ; la procdure sera place ici 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

START :

BEGIN :

MOV AX, CODE MOV DS, AX MOV ES, AX Etq1 : MOV CX, N-1 CALL FINDMAX CMP BL, 0 JZ Fin DEC CX LOOP Etq3 BRK ENDS END START

Etq3 :

FINDMAX

Fin : CODE

Remarques : Le compteur CX est utilis par le programme principal, mais il nest pas ncessaire de lempiler avant lexcution de la procdure du sous-programme, car cette dernire ne modifie pas le contenu de CX. Il est possible aussi de faire lempilement de CX dans le programme principal juste avant le CALL et de faire son dsempilement dans le programme principal aussi juste aprs le CALL. Le registre BL ne peut pas tre empil et dsempil par le programme principal, car la valeur retourne par le sous-programme ne doit pas tre perdue avant son utilisation dans linstruction (CMP BL, 0) qui vient aprs le sous programme.

On rappelle que pour un programme dont lensemble des segments ne dpasse pas les 64 Ko, alors, le programme est organis selon le canevas suivant :
; nom du programme CODE SEGMENT ASSUME CS:CODE, DS:CODE ES:CODE, SS:CODE ORG 0100H placer toutes les EQU ici START : JMP BEGIN placer tous les define ici placer toutes les procdures ici BEGIN : CODE ENDS END START placer votre programme ici

13

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 rsultat sera plac ladresse [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 procdure rcursive (qui fait appel elle-mme) : programme
;pgdcom CODE START :

sous-programme
PGDC SEGMENT ASSUME ORG JMP CS:CODE, DS:CODE ES:CODE 0100H BEGIN 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

; la procdure sera place ici BEGIN : MOV AL, [200] MOV BL, [201] CBW ; forcer AH = 0 CALL PGDC MOV [202], AL BRK ENDS END START FIN : PGDC

CODE

Remarque : Les registres AH, AL, BH, BL sont employs par le programme principal et par la procdure, donc on doit les empiler avant de les utiliser par la procdure, puis les dsempiler aprs finir leur utilisation avec la procdure (PUSH et POP ne fonctionnent que sur des registres 16 bits).

14

Exercice 5 : Ecrire un programme qui puisse calculer un dixime prs la moyenne arithmtique de N = 100 valeurs se trouvant dans un tableau. Solution :
;moy CODE SEGMENT ASSUME ORG JMP

START : BEGIN :

CS:CODE, DS:CODE ES:CODE 0100H N EQU 100D 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 Dci MUL [0100H] DIV BL BRK ENDS END START

Boucle :

Fin : CODE

15

Exercice 6 : Ecrire un programme qui indique la prsence de la chane de caractres TEC568 qui dbute ladresse [300h], dans un tableau de N = 96 lments qui dbute ladresse [200h], (utiliser deux procdures AFICH_OK et AFFICH_NK pour afficher le rsultat). Solution : Dbut SI <-- 200h CX <-- N-5 DI <-- 300h BL <-- 6 CLD CMPSB NON Z = 1 ? OUI NON BL = 5 ? OUI DEC SI OUI

DEC BL NON Z = 1 ?

DEC CX NON Z = 1 ? OUI AFFICH_NK

AFFICH_OK

Fin

16

La longueur de la chane TEC586 est N = 6, la premire lettre T est donc cherche parmi les (N - N -1) premires valeurs ; et le compteur CX prend les valeurs suivantes (sa dernire valeur est toujours gales 1) : CX = N - (N - 1), N - (N - 1) - 1, ... 2, 1 Par exemple, si N = 15, on aura :
1 2 3 4 5 6 7 8 9 10 T CX = 10 9 8 7 6 5 4 3 2 1 11 12 E C 13 5 14 8 15 6

Le programme :
;moy CODE SEGMENT ASSUME ORG JMP

START : BEGIN :

CS:CODE, DS:CODE ES:CODE 0100H N EQU 96D 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

Etq1 : Etq2 :

Etq3 Etq4 Fin : CODE

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

17