Você está na página 1de 155

Assembleur

Niveaux de programmation

Niveaux de programmation
circuit logiques
0/1
--------------------------------------------------------------------------------unit de traitement
micro-instructions
(UAL, chemins de donnes)

(Unit de commande)

= suite de 0/1

micro-pgme
= suite de micro-instructions

-----------------------------------------------------------------------------------Codop
111111 000011101010101
langage machine
= suite de 0/1
-----------------------------------------------------------------------------------ADD A,20
assembleur = remplacer les codop
JZ 13
par des mnmoniques
Djamal Rebane

Structure dun programme


assembleur 8086
TITLE nom ; donner un nom au programme
PILE SEGMENT STACK ; dclaration dun segment de pile
; dont le nom est pile
..........
..........
PILE ENDS ; fin de la dclaration de la pile
DONNEE SEGMENT ; dclaration dun segment de donnes qui va
; contenir les variables
...........
DONNEE ENDS
; fin de la dclaration de donnes
LECODE SEGMENT ; dclaration du segment de code qui va contenir
; le code
Debut:
; tiquette dindication du point dentre du code
.................................
LECODE ENDS
; fin de la dclaration du code
END Debut
; fin du point dentre du code
Djamal Rebane

Exemple
TITLE prog2.asm: Exemple sur ROL,
Pile segment stack ;
dw 100 dup(?)
Pile ends
DATA segment
DATA1DW
COMPTE
DATA ends

5F97H
DB

CODE segment
MAIN:
ASSUME CS:CODE, DS:DATA
MOV AX,DATA
MOV DS, AX
XOR
MOV
MOV
ENCORE: ROL
JNC
INC
PROCHAIN: DEC
JNZ
MOV

MAIN

BL, BL
DL, 16
AX, DATA1
AX, 1
PROCHAIN
BL
DL
ENCORE
COMPTE, BL

MOV AH, 4Ch


INT
21h
ENDS
END MAIN

; Mettre BL 0 (ou bien SUB)


; rotation 16 fois
; Rotation a gauche (a droite aussi si on prfre)
; Test si CF=0
; Si CF = 1, incrmenter le compteur du nombre de 1
; rpter 16 fois
; encore une fois si ce nest pas fini
; sauvegarder le rsultat dans la case mmoire COMPTE

Djamal Rebane

Pourquoi les segments?


l'origine
- Pour pouvoir adresser plus de 64 Ko de mmoire dans un
programme car les registres sont sur16 bits
En pratique aujourd'hui
- Permet de sparer clairement des zones mmoires selon
leur rle
Exemple : la pile ne peut pas tre crase par des donnes ou
dborder sur des donnes / code
Mais cela est contraignant ...

Djamal Rebane

Suite
Adressage sur 20 bits avec 2 registres
2 registres 16 bits : peut coder adresses sur 32 bits
Pour uniquement 20 bits
- Dcale le premier registre de 4 bits et l'additionne au
second
- Adresse note A:B
- Adresse relle : A * 16 + B
Exemple (les nombres sont en hexa)
3100:27EE correspond l'adresse 31000 + 27EE = 337EE
Dcaler de 4 bits en binaire revient dcaler d'un chiffre
en hexa
Djamal Rebane

Suite 2
Nous avons 4 segments d'adresses : CS, DS, SS, ES
utiliser 2 registres pour adresser des mots mmoires
- Le premier est le registre de segment
- Le second un registre gnral
On l'appelle l'offset (dcalage)
Addresse : segment:offset
Exemples
- CS:IP : adresse de la prochaine instruction excuter
- DS:SI : adresse d'une donne
- SS:SP : adresse du haut de la pile
Djamal Rebane

Vos programme sources, crits en


assembleur, doivent avoir lextension
.asm pour ASseMbler

Djamal Rebane

Dclaration de variables
Les variables se dclarent de la manire suivante:
datas1 db ? ; datas1 est un byte non initialis
datas2 db 0FFh ; datas2 est un byte initialis FF (255 en hexadcimal)
datas3 dw ? ; datas3 est un word (16 bits)
datas4 db 5 dup (?) ; datas4 est un tableau de 5 bytes non initialiss
datas5 dw 10 dup (15) ; datas5 est un tableau de 10 byte initialiss 15
De manire gnrale:
DB
: 1 byte (8 bits) (Declare Byte)
DW
: 1 word (16 bits) (Declare Word)
DD
: 2 words (32 bits) (Declare Double)
DF,DP
: 6 bytes
DQ
: 8 bytes (64 bits)
DT
: 10 bytes
Les constantes peuvent tre crites en:
- dcimal: 1, 2, 3, 123, 45
- hexadcimal : 1h,2h,3h,12h,0Fh,0AD4h (noter la prsence du 0 quand le le premier
chiffre du nombre en hexadcimal commence par une lettre)
- binaire : 1b,0b,1010b,111101b

Djamal Rebane

Les entres Sorties en assembleur


Pour raliser les oprations standards (affichage, saisie), le systme
dexploitation (ici DOS) fournit les fonctions pr-crites suivantes:

Affichage dun caratre:

Affichage dune chaine de caractres:


mov DX, offset chaine; pointe vers ladresse du premier
caractre de la chane de caractres chaine
mov AH, 09h; fonction no. 9
int 21h;
Saisie dun caratre:
mov AH, 1; fonction no. 1
(avec cho)
int 21h ; rsultat est mis dans AL

mov DL, A; caractre A est transfre dans DL


mov AH, 2; fonction no. 2
int 21h
; appel au DOS

Djamal Rebane

10

Saisie dun caractre


(sans cho)

Arrt de programme:

mov AH, 7; fonction no. 7


int 21h
; rsultat dans AL

mov AX, 4C00h;


int 21h;
mettre la fin de chaque fin programme; cest lquivalent du
return (0) en C. Ces instructions ont pour effet de retourner au DOS

Djamal Rebane

11

Lquivalent de quelques instructions du langage C


en assembleur

if then else

Assembleur

If ax =1
bx = 10;
else {
bx = 0;
cx = 10;
}

if:

CMP AX, 1
JNZ Else

Then: MOV BX,10


JMP endif
Else: MOV BX,0
MOV CX,10
endif: ..............

Djamal Rebane

12

Instruction i

Instruction i
Si condition alors
Instructions j
Sinon
Instruction m
Fin si
Instructions k

VRAI

FAUX
Condition ?

Instructions m

Instructions j

Instructions k

Djamal Rebane

13

La boucle FOR

Assembleur

MOV BX,0
MOV CX,0
CMP CX,10
JA Endfor
ADD BX,CX
INC CX
JMP For

For (k=0; k<=10; k++)


bx = bx + k;
For:

Endfor:

Djamal Rebane

14

WHILE

bx = 5
while (bx >0)
bx = bx -1;

Assembleur
while:

MOV BX,5
CMP BX,0
JLE Endwhile
DEC BX
JMP while

Endwhile:

Djamal Rebane

15

SWITCH

switch (n) {
case 1: ....; break;
case 2: .....; break;
default: .....;
}

Assembleur
CMP n,1
JNE case2
............
JMP endswitch
case2: CMP n,2
JNE default
..........
JMP endswitch
default: ...........
endswitch: ...........
Djamal Rebane

16

crire le code de linstruction


if (a>b) && (c <= d)
{

En assembleur
if: cmp a, b
jng endif

................
}

cmp c, d
jnle endif
..............
endif:

Exercice: coder en assembleur les instructions suivantes:


1. if (a >b) || (c > d))
2. for (i=1; i < 10; i++)
{
{
}

}
Djamal Rebane

17

Liste des registres les plus utiliss


A. Registres gnraux
AX (A pour accumulateur): joue le rle doprande implicite dans
plusieurs oprations: MUL, DIV, INC, etc.
CX (C pour compteur): est utilis pour les boucles (instruction
LOOP).
DX: utilis dans les multiplications et divisions comme registre
dextension.
SI (Source Index): souvent utilis comme pointeur sur une adresse
mmoire (exemple: MOV AL, [SI]). Il est trs utilise avec les
instructions de traitement de chanes de caractres (LODS).
DI (Destination Index): pareil que SI (instruction STOS)
BP (base pointeur): sert de pointeur sur la base de la pile, et permet
datteindre nimporte quel lment de la pile (exemple:
MOV AX,[BP+2]).
SP (Stack pointer): pointe sur le sommet de la pile; son contenu est
automatiquement chang par les instructions PUSH et POP.

Djamal Rebane

18

B. Registres spciaux
IP (Instruction pointeur): contient ladresse de linstruction qui suit
celle qui est en cours dexcution.
DS (Data Segment): Pointe sur le dbut du segment qui contient
les donnes
CS (Code Segment): Pointe sur le segment qui contient le code du
programme.
ES (Extended Segment) : permet de pointer sur un segment
supplmentaire dfini par le programmeur. Il se charge par
lintermdiaire de AX, comme pour DS.
SS (Stack Segment): segment contenant la pile.
C. Registre indicateur : utilis pour sauvegarder des tats particuliers
du microprocesseur en rfrence la dernire instruction excute.
Quelques bits seulement de ce registre ont une signification sont
nomms: CF (retenue), OF (dbordement), etc.

Djamal Rebane

19

Djamal Rebane

20

Format standard dune instruction


Label: Mnmonique Oprandes ;commentaire
Label: est un identificateur permettant de dsigner un endroit dans le
code source, soit une instruction, soit une donne. Si le label est
plac avant une instruction, on fait rfrence ladresse de cette
instruction. Si cest avant une donne, on fait rfrence ladresse
de cette instruction.
Le label de code doit se terminer par deux points (:). Il sert gnral
comme destinations des instructions ou des retour de dbut des
boucles de rptition.
Le label de donne ne contient pas les deux points(:) la fin. Il sert
dans ce cas l comme identificateur.

Djamal Rebane

21

Mnmonique (des instructions): il sert


identifier une instruction donne. Quelques
instructions de base sont rsumes dans la
prochaine section.
Oprandes: une instruction assembleur peut
avoir de 0 3 oprandes. Chaque oprande
peut tre le nom dun registre, un oprande
mmoire, une expression constante ou le nom
dun priphrique entre/sortie.
Commentaire: prcd du point-virgule (;). Il
sert ajouter des informations explicatives au
sujet du fonctionnement du programme ou de
linstruction correspondante.
Djamal Rebane

22

Quelques instructions de base-1


Affectations
; Registres <-- Valeurs
MOV AX, 65535
; (dcimal)
MOV Cl, 01101b
; (binaire)
MOV DH, 0FAh
; (hexa)
; Entre registres
MOV AX, BX
MOV CL, DH
; Entre Registres et Variables
MOV CX, variable_de_deux_octets
MOV variable_de_un_octet, DL
;Registres <-- Adresses Mmoire
Mov AX, Offset variable ; AX <- adresse de variable
Mov CX, [ 5Ah ]
; CX <- valeur l'adresse 5A en hexa
Djamal Rebane

23

Quelques instructions de base- 2


Arithmtique
; Incrmentation
INC AX
; AX <- AX + 1
Inc ma_variable
; Dcrmentation
DEC AX
Dec ma_variable
; Addition
ADD AX, 5
; AX <- AX + 5
ADD BH, toto
; BH <- BH + toto
Add toto, Cx
; toto <- toto + Cx
; Soustraction
SUB AX, 5
; AX <- AX 5
SUB BH, toto
; BH <- BH toto
SUB toto, CX
; toto <- toto - CX
Djamal Rebane

24

Quelques instructions de base-3


Logique
; AND bit bit
MOV AH, 0101b
MOV BH, 1001b
AND AH, BH
; OR bit bit
MOV AH, 0101b
MOV BH, 1001b
Or AH, BH
; XOR bit bit
MOV AH, 0101b
MOV BH, 1001b
XOR Ah, BH
; NOT bit bit
MOV AH, 0101b
(8+2)

; AH <- 5
; BH <- 9
; AH <- AH AND BH; AH vaut 0001b, soit 1
; AH <- 5
; BH <- 9
; AH <- AH OR BH; AH vaut 1101b, soit 13 (8+4+1)
; AH <- 5
; BH <- 9
; AH <- AH XOR BH; AH vaut 1100b, soit 12 (8+4)
; AH <- 5 Not AH ; AH <- NOT AH; AH vaut 1010b, soit 10
Djamal Rebane

25

Quelques instructions de base-4


Comparaisons :
Toutes les comparaisons se font l'aide de l'instruction CMP.
On utilise ensuite les instructions de saut conditionnel:
Jump if Equal,
JMP if Greater, ...
Il faut dfinir des labels (tiquettes): les endroits dans le programme o va sauter si
le test est vrifi (comme les GOTO en Fortran).
; Egalit (Jump if Equal)
CMP AX, 5
JE label_1
; Diffrence (Jump if Not Equal)
CMP AX, ma_variable
JNE label_2
;Infrieur, Suprieur, Inf. ou gal, Sup. ou gal
; (Jump if Lower, Greater, Lower or Equal, Greater or Equal)
CMP CH, 0
JL label_1
CMP DH, Ah
JG label_2
CMP AL, 01001b
JLE label_3
Djamal Rebane

26

CMP variable, 65
JGE label_4
Label_1: instructions...
Label_2: instructions...
Label_3: instructions...
Label_4: instructions...
; Saut non conditionnel :
JMP label_1
Remarque: CMP est identique linstruction SUB, mais ne produit pas de
rsultat. Il positionne cependant les flags. Il permet de sauter un label qui
est une adresse de 16 bits. Les sauts un label sont toujours courts (
peu prs de 127octets). Il faut donc prendre garde que ce label puisse tre
atteint.

Djamal Rebane

27

Djamal Rebane

28

JZ

Saut si zro.

JE

Saut si gal.

JC

Saut si Retenue (infrieur).

JNC

JB

Saut si infrieur.

JNB

JNAE

Saut si ni suprieur ni gal.

CF = 1

JAE

JS

Saut si signe ngatif.

SF = 1

JNS

JO

Saut si dbordement.

OF = 1

JNO

JPE

Saut si parit paire.

JP

Saut si parit.

PF = 1

JPO

JNZ

Saut si pas zro.

JNE

Saut si diffrent.

JNC

Saut si pas de retenue.

JC

JNB

Saut si pas infrieur.

JB

JAE

Saut si suprieur ou gal.

CF = 0

JNAE

JNS

Saut si aucun signe (positif).

SF = 0

JS

JNO

Saut si pas de dbordement.

OF = 0

JO

JPO

Saut si parit impaire.

JNP

Saut si pas de parit.

Djamal Rebane

JNZ
ZF = 1

JNE

JZ
ZF = 0

JE

JPE
PF = 0

JP

29

Modes dadressage
Un mode d'adressage est un moyen qui permet au
microprocesseur d'avoir accs une donne.
Cette donne peut tre un nombre quelconque
dont on aura besoin dans le programme, un
nombre qui se trouve dj dans un registre, ou
encore un nombre qui se trouve crit quelque
part en mmoire.
La connaissance des principaux modes
d'adressage est ncessaire car elle permet
d'crire les programmes de la faon la plus
courte, la plus simple et la plus lisible possible.
Djamal Rebane

30

Modes dadressage
Mode immdiat
Loprande est code avec linstruction
mov AX, 568
Mode registre
Loprande est un registre de donne ou dadresse
mov AX,BX
Mode mmoire direct
Loprande est dsign par ladresse donne dans linstruction
mov
[0hC040],AL
mov
DS :[0hC040],AL
mov
CS:var2,AX
mais pas
mov
0hFE15 :var2,AX

Djamal Rebane

31

Modes dadressage pour


accder aux donnes
Mode mmoire indirect
Loprande est dsigne par une adresse place dans les
registres dadresses donne dans linstruction
mov AX,[SI]
BX,BP,SI,DI peuvent servir de registre
pointeur
1. Indirect avec dplacement
Ladresse = contenu du registre dadresse + dplacement
(le registre dadresse nest pas modifi)
mov
AX, [DI]
mov
BX,[DI+6]

Djamal Rebane

32

Modes dadressage pour


accder aux donnes
2. Indirect avec index
Ladresse = contenu du registre dadresse
+ contenu du registre dindex (le registre
dadresse nest pas modifi)
mov [BP][DI],AX
les couples possibles sont BP-DI,
BP-SI, BX-DI, BX-SI
Djamal Rebane

33

Quelques notes utiles


La dclaration dune chane de caractres est mise en
'' '' ou ' ' .
Le caractre '$' indique la fin dune chane de caractres. Son
omission implique que les octets en mmoire qui viennent
aprs cette chane sont aussi affichs comme des caractres.
Lassembleur ne fait pas de diffrence entre une majuscule et
une minuscule dans lcriture de ses instructions et la
notation des registres.
La directive ASSUME permet d'indiquer l'assembleur o se
situe le segment de donnes et le segment de code. Puis il
s'agit d'initialiser le segment de donnes lintrieur du
segment de code:
MOV AX, nom_du_segment_de_donnees
MOV DS, AX

Djamal Rebane

34

Un petit mot sur linstruction


de transfert
MOV reg, reg (registre registre)
reg, mem (registre mmoire)
mem, reg (mmoire registre)
reg, imed (registre valeur)
mem, imed (mmoire valeur)
NOTE: Pas de transfert de mmoire mmoire

Djamal Rebane

35

Applications de quelques
instructions sur des exemples

Djamal Rebane

36

Instruction CMP (Comparer)

CMP destination, source

Linstruction CMP affecte les indicateurs AF, OF, SF, PF, CF et ZF


mais seuls CF et ZF sont utiliss.
Loprande destination peut tre dans un registre ou dans une mmoire.
Loprande source peut tre dans un registre, dans une mmoire, ou en mode immdiat.
Les oprandes (destination et source) ne changent pas.
DATA1

PASSE:
TEMP

DW

235FH

MOV
MOV
CMP
JNC
ADD
ADD

BX, 7888H
CX, 9FFFH
BX, CX
PASSE
BX, 4000H
CX, DATA1

DB

MOV
CMP
JZ
INC
PROCHAIN: HLT

AL, TEMP
AL, 99
PROCHAIN
BX

; 7888Hh BX

Compar
e
Oprand
es

C
F

ZF

Dest. >
Src.

Dest. =
Src.

Dest. <
Src.

; BX < CX CF=1 JNC est excute PASSE


; Note: les contenus de (BX, et CX) ne changent pas aprs CMP
; mais CF est toujours vrifi pour (< ou >). Pour (=) on utilise ZF.

; TEMP AL
; TEMP = 99?. Avec (SUB AL, 99), la mme chose mais 0 AL
; Si ZF=1 (TEMP=99), Saute a PROCHAIN:
; Sinon incrmente BX
; Arrt du programme

Djamal Rebane

37

TITLE prog1.asm: Exemple sur CMP, Trouver loctet le plus grand parmi 5 notes dlves
PILE segment stack
dw 100 dup(?)
PILE ends
;------------------------------------------------------------------------------------------------------------------------------------------------------------DATA segment
NOTES
DB
18, 06, 19, 11, 08
PLUS_G
DB
?
DATA ends
;-----------------------------------------------------------------------------------------------------------------------------------------------------------CODE segment
main:
assume CS:CODE, DS:data ; gnration de ladresse du segment de code et de donnes
MOV AX, DATA
; Initialiser le registre DS pour rcuprer ladresse du segment de donne
MOV DS, AX
MOV CX, 5
; compteur de boucle
MOV BX, OFFSET NOTES
; BX pointe vers les donnes NOTES
XOR
AL, AL
; Initialise AL 0; va hberger la plus grande note
ENCORE: CMP AL, [BX] ; compare la note prochaine a la note la plus leve
JA
PROCHAIN
; Sauter si AL est encore la note la plus leve
MOV AL, [BX]
; sinon AL retient la plus leve
PROCHAIN: INC BX
; pointe vers la prochaine note
LOOP ENCORE
; CX dcrmente jusqu 0 pour sortir de la LOOP
MOV PLUS_G, AL
; sauvegarde de la note la plus leve dans PLUS_G
;------------------------------------------------------------------------------------------------------------------------------------------------------------MOV AH, 4Ch
INT
21h
MAIN ENDS
END
MAIN

Djamal Rebane

38

TITLE prog2.asm: Exemple sur ROL, Trouver le nombre de 1 dans un mot


Pile segment stack ; dclaration dun segment de pile pas ncessaire dans notre cas
dw 100 dup(?)
Pile ends
;-----------------------------------------------------------------------------------------------------------------------------------------------------------DATA segment
DATA1DW
5F97H
COMPTE
DB
?
DATA ends
;------------------------------------------------------------------------------------------------------------------------------------------------------------CODE segment
MAIN:
ASSUME CS:CODE, DS:DATA
MOV AX,DATA
MOV DS, AX
XOR
BL, BL
; Mettre BL 0 (ou bien SUB)
MOV
DL, 16
; rotation 16 fois
MOV
AX, DATA1
ENCORE: ROL
AX, 1
; Rotation a gauche (a droite aussi si on prfre)
JNC
PROCHAIN
; Test si CF=0
INC BL
; Si CF = 1, incrmenter le compteur du nombre de 1
PROCHAIN: DEC DL
; rpter 16 fois
JNZ ENCORE
; encore une fois si ce nest pas fini
MOV COMPTE, BL
; sauvegarder le rsultat dans la case mmoire COMPTE
;-----------------------------------------------------------------------------------------------------------------------------------------------------------MOV AH, 4Ch
INT
21h
MAIN ENDS
END MAIN

Djamal Rebane

39

Quelques explications
Litration: On peut galement transcrire une boucle laide de
linstruction LOOP ncessitant lutilisation implicite du registre CX.
MOV CX, unevaleur
Boucle:
; le corps de la boucle
LOOP Boucle
Cela signifie que le corps de la boucle est excut tant que la valeur
de CX nest pas nulle. A chaque itration, CX est dcrment dune
unit.
Attention: si CX est nul au premier tour, alors il dcrment et sa
valeur devient 65535, et on va attendre un bon bout de temps pour
arriver la valeur nulle et sortir de la boucle

Djamal Rebane

40

for (cx=5; cx>0; cx--)


ax = ax + cx
MOV AX,0
MOV CX,5 ; CX est le compteur de boucle
for:
ADD AX,CX ; fait le calcul
LOOP for ; dcrmente dune unit CX.
; si CX > 0 fait le saut for
Djamal Rebane

41

On peut aussi utiliser LOOPE/LOOPZ/LOOPNE/LOOPNZ


pour signifier :
a.LOOPE ( Loop while Equal ) Monlabel
Dcrmente CX, puis, si CX <> 0 et ZF = 1, fait un saut
MonLabel.
Mnmonique quivalent : LOOPZ
b. LOOPNE ( Loop while not Equal ) Monlabel
Dcrmente CX, puis, si CX <> 0 et ZF = 0, fait un saut
MonLabel.

Djamal Rebane

42

Buffer DB 8 DUP(0)
..
Boucle:
MOV AH,1 ;lecture
INT 21h
MOV [BX], AL; rangement de quon vient de lire
INC BX
CMP AL, 0Dh; a-t-on lu le retour chariot?
LOOPNE Boucle; sinon on continue jusqu CX = 0 ????

Djamal Rebane

43


Dcalage et rotation
SHL (Shift Left; SHR: shift right): effectue un dcalage gauche des bits. Si le deuxime
oprande est une valeur, alors seule la valeur 1 est accepte. Le bit de poids fort
se retrouve dans CF; un 0 est introduit dans le bit de poids faible.
SHL AL, 1

Une faon plus lgante consiste utiliser CL dans son rle de compteur:
MOV CL, 4
SHL AX,CX
Pareil pour les instructions SAR, ROR, RCR et leurs quivalents gauche.

Djamal Rebane

44

Manipulation de donnes
1.
Operateur offset: renvoie ladresse laquelle est situe un label de donne
Exemple:

Bval
db ?
Wval1
dw ?
Wval2
dd ?

Si Bval se trouve ladresse offset 00404000 (hexa), loprateur offset renvoie les
valeurs suivantes:
MOV AX, offset bval
; AX = 00404000
MOV AX, offset Wval1 ; AX = 00404001
MOV AX, offset Wval2 ; AX = 00404002
2. Operateur PTR: Permet de passer outre la taille dclare au dpart pour un
oprande. Par exemple,

double dd 12345678h

MOV AX, double; erreur


Mais si on insre la directive WORD PTR, on peut copier le mot de poids faible (5678h)
dans AX; cest--dire
MOV AX WORD PTR double

Djamal Rebane

45

Un mot sur les macros


tant donn que certaines instructions se rptent
constamment dans un programme, lcriture de
macro-fonctions (ou macros) est un moyen
pratique de rendre votre code source plus lisible.
Il est possible de choisir pour certaines suites
dinstructions un nom qui les reprsente.
Lorsque lassembleur rencontrera ce nom dans
votre code source, il le remplacera par les lignes
de code quil dsigne. Ces lignes forment une
macro .

Djamal Rebane

46

Les macros, la diffrence des procdures, nont aucune


signification pour la machine. Seul lassembleur
comprend leur signification. Elles ne sont quun artifice
mis la disposition du programmeur pour clarifier son
programme. Lorsque lassembleur rencontre le nom
dune macro dans votre code, il le remplace par le code
de la macro. Tout se passe exactement comme si vous
aviez tap vous-mme ce code la place du nom de la
macro.
Ainsi, si vous appelez quinze fois une macro dans votre
programme, le compilateur crira quinze fois le code de
cette macro. Cest toute la diffrence avec les fonctions
qui ne sont crites quune seule fois mais peuvent tre
appeles aussi souvent quon veut laide dun CALL
(quon verra plus tard dans ce cours).

Djamal Rebane

47

Voici comment crire une macro :


lexemple suivant sert crire un message
lcran.

Djamal Rebane

48

affiche macro chaine


; sauvegarder le contenu de DX, par
; exemple, en utilisant la pile
push dx ; sauvegarde de dx dans la pile
mov dx,offset chaine
mov ah, 09h
int 21h
pop dx ; restauration de dx
endm ;fin de la macro
Djamal Rebane

49

Lassembleur se chargera alors de la remplacer


par les instructions comprises entre la premire
et la dernire ligne de cet exemple, en prenant
le soin de remplacer le mot chaine par le
message fourni en paramtre.
Supposons prsent que lon veuille crire
lcran le message Coucou ! Ceci est un essai
et revenir la ligne laide de notre macro
affiche
La syntaxe suivante :
affiche Coucou ! Ceci est un essai !, 10, 13, $
10, 13 est lquivalent de endln en C-C++
Djamal Rebane

50

Prsentation dautres exemples

Djamal Rebane

51

TITLE ex3_somme; somme de deux nombres


PILE SEGMENT STACK; dclaration de pile.
; Pour cet exemple, la pile nest pas ncessaire.
DW 100 DUP (?)
PILE ENDS
affiche macro chaine
; macro pour afficher une chane de
; caractres
MOV DX,offset chaine ; offset renvoie ladresse de dbut de chaine
MOV AH, 09h
; fonction qui affiche une chane de caractres
INT 21h
ENDM; fin de la macro
DATA SEGMENT; dclaration de variables
val1 db 0
val2 db 0
recup_val1 db 10,13,'veuillez taper la valeur1',10,13,'$' ; 10 et 13=endl du C+
+
recup_val2 db 10,13,'veuillez taper la valeur2',10,13,'$
aff_resu db 10,13,'la valeur saisie est:',32,'$' ; $ caractre de fin de chaine
DATA ENDS
Djamal Rebane

52

SCODE SEGMENT ; zone de code


ASSUME CS:SCODE, DS:DATA ; gnration de ladresse du segment de
code et de donnes
DEBUT:
; entre du code
MOV AX, DATA ; Initialiser le registre DS pour rcuprer ladresse du
MOV DS, AX
; segment de donne
; partir dici on peut placer nos lignes de code
affiche recup_val1; appel de macro pour afficher un message contenu
dans recup_val1
MOV AH,1 ; faire une lecture au clavier grce la fonction 1 le caractre
tap sera plac dans AL
INT 21h
MOV val1,AL
affiche recup_val2; appel de la macro pour afficher un message sur cran
MOV AH,1 ;faire une lecture au clavier
INT 21h
ADD AL,val1 ; AL = AL + val1
MOV val2,AL

Djamal Rebane

53

affiche aff_resu; appel de la macro pour afficher un message sur cran


SUB val2,30h ; les valeurs lues tantt sont en ascii; exemple :
; si on tape les valeurs 1 et 2,
; le programme rcupre 31 et 32, valeurs
; hexadcimales des caractres 1 et 2.
; Donc 31 + 32 = 63. et 63 nest pas la valeur hexa
; du caractre 3. Sa valeur est 33
; autrement dit, on doit retirer 30 en hexa ou 48 en
; dcimal.
MOV AH,2 ; afficher la valeur saisie grce la fonction 2
INT 21h
; qui affiche le contenu de DL
MOV DL,val2
MOV AH, 4Ch ; on termine le programme avec la fonction
MOV AL, 0
; 4c en hexa. On place une valeur >=0 pour dire
INT 21h
; que lexcution sest droule correctement.
; quivalent en c de return 0
SCODE ENDS; fin du segment de code
END DEBUT
Djamal Rebane

54

TITLE ex4_max ; dtermine et affiche le maximum de deux nombres


; introduits travers le clavier
PILE SEGMENT STACK
DW 100 DUP (?)
; dclaration dune pile de 100 lments
PILE ENDS
affiche macro chaine
; la compilation, lassembleur recopie lensemble
; de instructions de cette macro
mov dx,offset chaine ; pointe vers le dbut de la chane chaine
mov ah, 09h
; pour afficher une chane de caractres partir de
; ladres de dbut de chaine
int 21h
Endm
DATA SEGMENT
temp db 0
; initialisation de temp 0
val1 db 0
val2 db 0
recup_val1 db 10,13,'veuillez taper la valeur1',10,13,'$' ; 10 et 13=endl du c++
recup_val2 db 10,13,'veuillez taper la valeur2',10,13,'$'
aff_resu db 10,13,'le maximun est :',32,'$' ; $ caractre de fin de chane
DATA ENDS

Djamal Rebane

55

SCODE SEGMENT
ASSUME CS:SCODE, DS:DATA ; gnration d,adresses pour les segments de code et de
donnes
DEBUT: ; entre du code
; Initialiser le registre DS par ladresse du segment de donne gnre par
; la directive ASSUME
MOV AX, DATA
MOV DS, AX
affiche recup_val1 ; permet dafficher le message contenu dans recup_val1
MOV val1,AL
MOV AH,1 ;faire une lecture au clavier dun caractre
INT 21h
affiche recup_val2 ; afficher un message
MOV AH,1 ; faire une lecture au clavier
int 21h
MOV val2,AL
CMP AL,val1
JG grand

Djamal Rebane

56

MOV DL,val1
JMP sortie
grand: MOV DL,val2
sortie: MOV temp,DL
affiche aff_resu ; afficher un message
MOV DL temp; ces trois instructions servent
; afficher le contenu du registre dl
MOV AH,2
INT 21h
; Terminer le programme en retournant vers le DOS
MOV AH, 4Ch
MOV AL, 0
INT 21h
SCODE ENDS
; fin du segment de code
END DEBUT ; fin de lentre du code
Djamal Rebane

57

Exemple 5: que fait cette portion de code?

MOV BX, offset Alphabet


;alphabet tant une chane de caractres
MOV CL, 26
MOV [BX], CL
; 26 caractres
MOV AL, 65h
; 65 = 'A' dans AL
MaBoucle: INC BX
MOV [BX], AL
; crit dans le tableau
INC AL
; AL = caractre suivant
DEC CL
; affecte linicateur ZF
JNZ MaBoucle
; test lindicateur ZF = 0
XOR BX, BX
; permet de mettre BX 0
MOV BX,offset alphabet
MOV CL,26
Boucle:
INC BX
MOV DL, alphabet[bx]
MOV AH,2
INT 21h
MOV DL, ; permet dafficher un blanc
MOV AH, 2
INT 21h
DEC CL
JNZ Boucle

Djamal Rebane

58

Exemple 6 : que fait la portion de code ci-dessous ?


MOV BX, offset Chose
; Met ladresse de dbut du tableau chose
dans BX
MOV DI, 0
; Index nul
MOV AX, 1
MOV CX, 11
; 11 lments dans le tableau
MaBoucle: MOV [BX+DI], AX ; crit dans le tableau
SHL AX, 1
; AX = AX * 2
ADD DI, 2
; Chose est un tableau de Words -> 2
octets
DEC CX
JNZ MaBoucle
Remarque 1 : Lors de la saisie dune chane de caractres au clavier,
les deux premiers termes sont rservs: le premier tant la
dimension et le deuxime est le nombre effectif de caractres.
Remarque 2 : Les registres SI, DI, BX peuvent tre utiliss pour les
indices de tableaux indiffremment.
Djamal Rebane

59

TITLE sommedetroixnombres ; ce programme fait la somme des trois


premiers nombres entiers i.e : 1+2+3
PILE SEGMENT STACK
DW 100 DUP (?)
PILE ENDS
affiche macro chaine; dclaration de macro
mov dx,offset chaine
mov ah, 09h
int 21h
endm; fin de la macro
DATA SEGMENT
temp db 0
val1 db 3
val db 0
aff_resu db 10,13,'la somme des termes jusqu a 3 est:',32,'$' ; $
caractre de fin de chane
DATA ENDS
Djamal Rebane

60

SCODE
SEGMENT
ASSUME CS:SCODE, DS:DATA
DEBUT: ; Initialiser le registre DS
MOV AX, DATA
MOV DS, AX
MOV AX,0
so:
CMP AH,val1
JGE psorte
INC AH
ADD AL,AH
JMP so
psorte: ADD AL,30h
MOV temp,AL
affiche aff_resu; affichage laide de la macro
MOV AL,temp
MOV DL, AL
MOV AH,2 ; afficher la valeur saisie
INT 21h
; Terminer le programme
MOV AH, 4Ch
MOV AL, 0
INT 21h
SCODE
ENDS
END DEBUT

Djamal Rebane

61

Exemple 7: Exemple sur ROL, Trouver le


nombre de 0 dans un double-mot

Djamal Rebane

62

TITLE programme.asm: Exemple sur ROL, Trouver le nombre de 0 dans un double-mot


PILESEGMENT STACK
DW 100 DUP (?)
PILEENDS
DATA
SEGMENT
DATA1
DD
0ABCD5F97H
COMPTE DB
?
DATA
ENDS
CODE
SEGMENT
ASSUME CS:SCODE, DS:DATA ; Initialiser le registre DS
MOV AX, DATA
MOV DS, AX
XOR
CX, CX
; Mettre CX 0 (ou bien SUB)
MOV
DX, 1010h
; mettre 16 dans DH et DL; 00010000 000010000 en binaire
MOV
AX, WORD PTR DATA1 ; pointer vers le premier mot
MOV
BX, WORD PTR DATA1 + 2
; pointe vers le deuxime mot
ENCORE1: ROL
AX, 1
; Rotation gauche ( droite aussi si on prfre)
JC
PROCHAIN1
Test si CF=1
INC
CL
; Si CF = 0, incrmenter le compteur du nombre de 0
PROCHAIN1: DEC DL ; rpter 16 fois
JNZ ENCORE1
; encore une fois si ce nest pas fini
MOV AL, CL
; sauvegarder le rsultat dans AL, en sortant de la boucle, le contenu de AX
; nous importe peu, donc en crasant le premier mot nest pas grave
ENCORE2: ROL BX, 1 ; Rotation gauche
JC PROCHAIN2
; Test si CF=1
INC CH
; Si CF = 0, incrmenter le compteur du nombre de 0
PROCHAIN2: DEC DH
; rpter 16 fois
JNZ ENCORE2
; encore une fois si ce nest pas fini
MOV AH, CH; sauvegarder le rsultat dans AH. Mme remarque quen haut
ADD AH, AL ; Additionner les nombres de 0 trouvs sparment dans les 2 mots
MOV COMPTE, AH
; et sauvegarder le rsultat dans COMPTE
MOV AH, 4Ch
; retour au DOS
INT 21h
Code ENDS
END MAIN

Djamal Rebane

63

Conversion Minuscule en
Majuscule
L

Hex

Binaire

Hex

Binaire

41

01000001

61

01100001

42

01000010

62

01100010

59

01011001

79

01111001

5A

01011010

7A

01111010

Djamal Rebane

64

TITLE prog8.asm ; Conversion MINUSCULE MAJUSCULE dun texte


PILE
SEGMENT STACK
DW 100 DUP (?)
PILE ENDS
DATA SEGMENT
TEXTE1
DB
mOn Nom eST REBainE, 13,10, $
TEXTE2
DB
21 DUP(?)
;-----------------------------------------------------------------------------------------------------------------------------------------------------------CODE
SEGMENT
ASSUME CS:SCODE, DS:DATA
; Initialiser le registre DS
MOV AX, DATA
MOV DS, AX MAIN :
MOV SI, OFFSET TEXTE1
; SI pointe sur le texte original
MOV BX, OFFSET TEXTE2
; BX pointe sur le texte en MAJUSCULE
MOV CX, 21
; compteur de boucle
ARRIERE: MOV
AL, byte ptr t[SI]
; prochain caractre
CMP AL, 61H
; Si < a
(61H est le code ASCII de a)
JB
PASSE
; donc pas besoin de convertir
CMP AL, 7AH
; Si > z
(7AH est le code ASCII de z)
JA
PASSE
; donc pas besoin de convertir
AND
AL, 11011111B
; masque le bit 5 pour convertir en MAJUSCULE
PASSE:
MOV
[BX], AL
; sauvegarde le caractre MAJUSCULE
INC
SI
; incrmente le pointeur vers le texte original
INC
BX
; incrmente le pointeur vers le texte en MAJUSCULE
LOOP ARRIERE ; Continuer boucler tant que CX > 0
;-----------------------------------------------------------------------------------------------------------------------------------------------------------MOV AX, 4C00h
INT 21h
CODE
ENDS
END
MAIN

Djamal Rebane

65

Exemple 9: lit une chane de caractres et


laffiche lenvers
Programme palin

Djamal Rebane

66

title palin
pile segment stack
dw 100 dup(?)
pile ends
data segment
reponse db 255 dup('$')
enter db 10,13,'$
; endln en C++
temp db 0
data ends
scode segment
assume cs:scode, ds:data
entree:
mov ax,data
mov ds,ax
; on crit le code partir de l
mov dx,offset reponse
mov ah,0ah ; lecture partir du clavier dune chane de caractres
;qui se termine ds quon tape le retour chariot (touche entre)
int 21h
mov si,dx
mov cx,si

Djamal Rebane

67

Deb: cmp BL,0dh; comparer la touche entre 13 en ascii car la fin de reponse contient ce caractre
je finsearch
inc SI
mov BL,byte ptr[si]
jmp deb
finsearch:
dec SI
inc CX
mov DX,offset enter
mov AH,09h
int 21h
fs:
cmp SI,CX
je fin_s
mov DL,byte ptr[si]
mov AH,02h
int 21h
dec SI
jmp fs
fin_s:
mov ax,4c00h
int 21h
scode ends
end Deb

Djamal Rebane

68

Une autre manire de le faire

;debut:
xor dx,dx
mov DL,[si+1] ; rcupration du nombre de caractres lus
; la taille rcuprer est obtenue par lobjet de destination
; car [si+1] na pas de taille spcifique donc obligation de la
; rcuprer avec la destination
; ici DL donc rcupration de 8bits ; si DX rcupration de 16bits
; la destination dcide de la taille rcuprer
mov si,dx
inc si
mov cx,1
f_s:
cmp si,cx
jle fin_s
mov dl,reponse[si]
mov ah,02h
int 21h
dec si
jmp f_s
fin_s:
mov ax,4c00h
int 21h
scode ends
end

Djamal Rebane

69

Une troisime manire de le faire

debut:
xor DX,DX
mov DX,reponse[si] ; rcuperation du nombre de caractres lus
; la taille rcuprer est obtenue par lobjet de destination
; ici DL donc rcupration de 8bits si DX rcupration de 16bits
; la destination dcide de la taille rcuprer
mov SI,DX
inc SI
mov CX,1
fs:
cmp SI,CX
jle fins
mov DL,reponse[si]
mov AH,02h
int 21h
dec SI
jmp fs
fins:
mov AX,4c00h
int 21h
scode ends
end

Djamal Rebane

70

MULTIPLICATION ET DIVISION SIGNE


(ou mm.)

(IMUL / IDIV) reg.

Note: Dans les manuels dIntel IMUL et IDIV pour Integer MULtiplication
et DIVision (X et / des nombres entiers) mais au fait il sagit de
Multiplication et Division des nombres signes.
DIVISION SIGNEE

NUM. (> ou <)

DENOM. (> ou <)

QUOTIENT

RESTE

Octet/Octet

AL = Octet CBW

Reg. ou mem.

AL

AH

Mot/Mot

AX = Mot CWD

Reg. ou mem.

AX

DX

AX = Mot

Reg. ou mem.

AL (Erreur si 128>AL>+127)

AH

DXAX = DoubleMot

Reg. ou mem.

AX (Erreur si 32768>AX>+32767)

DX

Mot/Octet
DoubleMot/Mot
MULTIPLICATION
SIGNEE

OPERANDE 1
(> ou <)

OPERANDE 2
(> ou <)

RESULTAT

Octet/Octet

AL

Reg. ou mem.

AX (CF=OF=1 si AH possde une partie du rsultat,


mais si celui-ci nest pas large pas besoin de AH,
le bit de signe est copi aux bits non utiliss de AH et
la CPU force CF=OF=0 pour lindiquer)

Mot/Mot

AX

Reg. ou mem.

DXAX(CF=OF=1 si DX possde une partie du


rsultat, mais si celui-ci nest pas large pas besoin
de DX, le bit de signe est copi aux bits non utiliss
de DX et la CPU force CF=OF=0 pour lindiquer)

AL = Octet CBW

Reg. ou mem.

DXAX (mme remarque que prcdemment)

Mot/Octet
DoubleMot/Mot

Djamal Rebane

71

Title exemple pour trouver la moyenne dun ensemble de nombres


PILE segment stack
dw 100 dup (?)
PILE ends
DATA segment
SIGN_DAT DB
+13,-10,+19,+14,-18,-9,+12,-9,+16
MOYENNE DW
?
RESTE DW
?
DATA ends
CODE segment
ASSUME CS:CODE, DS:DATA
MOV
AX,DATA
MOV
DS,AX
MAIN:

ARRIERE:

MAIN

MOV
XOR
MOV
MOV
CBW
ADD
INC
LOOP
MOV
CBW
MOV
MOV

CX,9
BX,BX
SI,OFFSET SIGN_DAT
AL,[SI]
BX,AX
SI
ARRIERE
AL,9
CX,AX
AX,BX

; Charger le compteur
; Mettre a 0 le registre BX, utilis comme accumulateur
; SI SIGN_DAT
; Un octet de donne AL
; Extension du signe AX
; BX+AXBX
; SI+1 SI
; Boucler tant que CX > 0
; Le nombre totales des tempratures AL
; Extension du signe AX
; Sauvegarder le DENOMINATEUR dans CX
; LA somme des tempratures AX

EXEMPLE DUTILISATION DE IDIV TROUVER LA TEMPERATURE MOYENNE


CWD
; Extension du signe AX
IDIV
CX
; Trouver la moyenne des tempratures (AX/CX)
MOV
MOYENNE,AX
; Sauvegarder la moyenne (QUOTIENT)
MOV
REMAINDER,DX
; Sauvegarder le reste
MOV
AH,4CH INT 21H
;Retourner au DOS
ENDP
END
MAIN

Djamal Rebane

72

Expression arithmtique
X = (A*2 + B*C)/(D-3)
.......
Data segment
X dw ?
A dw ?
B dw ?
C dw ?
D dw ?
Data ends
Arithmetique proc near
MOV AX, 2
IMUL A
MOV BX,DX
MOV CX,AX
MOV AX,B
IMUL C
ADD AX,CX
ADC DX,BX
MOV CX, D
SUB CX,3
IDIV CX
MOV X,AX
RET
Arithmetique endp
............

;tablir la constante
;DX:AX = A*2
;
;BX:AX = A *2
;DX:AX = B*C
;AX = AX + CX ! faites attention, il peut y avoir une retenue ici
;DX:AX = A*2+B*C + la retenue sil y a lieu avec ADC
; cx = D -3
; AX =(A*2 + B*C)/(D-3)
; X = ax (A*2 +B*C)/(D-3) stocker le rsultat
; fin de la procedure

Djamal Rebane

73

Conversion dune chaine de caractres en


une valeur dcimale
Toute information introduite via le clavier est
considre comme une chane de
caractres. Ainsi, si on introduit le nombre
827, il sera considr par lassembleur
comme la chane de caractres 827.
Pour avoir sa valeur numrique, il y a lieu
de la convertir suivant lalgorithme suivant:

Djamal Rebane

74

Algorithme de conversion

nbre = nombre de caractre lus


Nombre = 0
Repeter
chiffre = caractre lu
nombre = nombre *10+chiffre
nbre = nbre -1
Si nbre > 0 aller repeter
Djamal Rebane

75

Exemple

827
nombre = 0
Chiffre = 8
nombre = nombre * 10 +chiffre =0*10+8 = 8
Chiffre = 2
nombre = nombre * 10 + 2 = 8*10 + 2 = 82
Chiffre = 7
Nombre = nombre * 10 + 7 = 82*10+7 = 827

Djamal Rebane

76

En assembleur, on aura quelque chose comme ci-dessous


TITLE caracteresversnombre
SPILE SEGMENT STACK
DW 100 DUP(?)
SPILE ENDS
SDATA SEGMENT
chaine db 255 dup('$')
SDATA ENDS
SCODE SEGMENT
ASSUME CS:SCODE,DS:SDATA
DEBUT:
mov AX,sdata
mov DS,AX
mov DX,offset chaine
mov AH,0ah
int 21h
mov SI,1
mov AX,0
xor CX,CX
mov CL,chaine[si]
inc SI
repeter:
mov DX,10
mul DX
mov DL,chaine[si]
sub DL,48; ou bien 30h, cest pareil. Cest pour rendre le caractre lu comme une valeur numrique
mov DH,0
add AX,DX
inc SI
loop repeter
MOV AX,4C00H
INT 21H
SCODE ENDS
END DEBUT

Djamal Rebane

77

Pour lire une chaine de caractres, appeler 21h fonction 0Ah qui installe les
caractres taps dans une zone repre par DS:DX (buffer dclare dans le
segment de donnes). La fonction se termine quand un return (touche
entre) est dtect. Le buffer contient alors les informations suivantes:
byte
0

contenu
nombre maximum de caractres lire

nombre de caractres lus (sans compter le retour chariot).


cette valeur est installe par la fonction.

partir de cette position, on trouve les caractres lus

Djamal Rebane

78

Conversion dune valeur dcimale en une


chane de caractres
Toute information affiche sur cran est considre comme un
caractre. Ainsi, pour afficher la valeur 827, il faut dans un premier
temps avoir tous le chiffres qui la composent; ensuite convertir
chacun de ces chiffres en leur quivalent ascii et ensuite passer
laffichage proprement dit.
Ainsi, si on veut afficher le 827, on doit dabord rcuprer les chiffres 8,
2 et 7 par une succesion de divisions par dix (ces chiffres seront
rcuprs dans lordre inverse). Ensuite, les convertir en ASCII en
ajoutant la valeur 30h, et enfin passer laffichage proprement dit
dans lodre inverse pour avoir le bon ordre.
Lalgorithme, rcuprant les chiffres dans lordre inverse, peut tre
comme suit:

Djamal Rebane

79

Algorithme
k=0
do
quotient = nombre / 10;
reste = nombre % 10;
tab[k] = reste;
nombre = quotient;
k++
while (quotient != 0)

Djamal Rebane

80

Dans ce programme, les chiffres composant le nombre contenu dans AX


est affich dans le bon ordre

on suppose que le registre AX contient le nombre


mov result,AX
; dclarer result dans le segment de donnes
mov dx,offset enter
; retour chariot 10, 13 dans le segment de donnes
mov ah,09h
int 21h
mov ax,result
mov SI, offset tabconv ; tabconv est dclarer dans le segment de donnes
mov start, offset tabconv
; start sert garder le dbut du tableau
mov BX,0
mov BL,10
division:
; on suppose que la division se fait sur des nombres de 16 bits
div BL
cmp AL,0
je fin_div
add AH,48
mov byte ptr[si],AH
mov AH,0
inc SI
jmp division
;

Djamal Rebane

81

fin_div:
add AH,48
mov byte ptr[si],AH
;tabconv contient le nombre converti lenvers
xor BX,BX
mov BX, offset tabsortie
; declarer dans le
segment de donnes
xor AX,AX
st_bcl:
cmp SI,start
jb fin_bcl
mov AH , byte ptr[si]
mov byte ptr[bx] , AH
dec si
inc bx
jmp st_bcl
Djamal Rebane

82

fin_bcl:
mov byte ptr[bx],10
inc BX
mov byte ptr[bx],13
inc BX
mov byte ptr[bx],'$'
mov dx,offset tabsortie
mov ah,09h
int 21h
MOV AX,4C00H
INT 21H
SCODE ENDS
END DEBUT
Djamal Rebane

83

La directive EQU
La directive EQU a un rle voisin de
celui des macros. Elle permet de
remplacer un simple mot par dautres
plus complexes. Son intrt est
quelle peut tre invoque en plein
milieu dune ligne.

Djamal Rebane

84

Quelques exemples
Longueur EQU (fin debut)
Message EQU Bonjour messieurs ! Comment
allez-vous ?, $
Version EQU 2
Quitter EQU ret
Quitter2 EQU int 20h
Mettre_dans_AH EQU mov ah,
Interruption_21h EQU int 21h

Djamal Rebane

85

Les piles

Djamal Rebane

86

Utilit d'une pile


Une pile est une zone de mmoire dans laquelle on peut stocker
temporairement des registres. Il s'agit d'un moyen d'accder des donnes
en les empilant, telle une pile de livre, puis en les dpilant pour les utiliser.
Ainsi il est ncessaire de dpiler les valeurs stocker au sommet (les
dernires avoir t stockes) pour pouvoir accder aux valeurs situes
la base de la pile.
En ralit il s'agit d'une zone de mmoire et d'un pointeur qui permet de reprer
le sommet de la pile.
La pile est de type LIFO (Last In First Out), c'est--dire que la premire
valeur empile sera la dernire sortie (Si vous empilez des livres, il vous
faudra les dpiler en commenant par enlever les livres du dessus. Le
premier livre empil sera donc le dernier sorti!).
Les instructions PUSH et POP
Les instructions PUSH et POP sont les instructions qui servent empiler et
dpiler les donnes.
- PUSH registre met le contenu du registre dans la pile (empilement)
- POP registre rcupre le contenu de la pile et le stocke dans le registre
(dpilage

Djamal Rebane

87

Ainsi, l'instruction
PUSH BX
empile le contenu du registre BX,
et l'instruction
POP AX
rcupre le contenu du sommet de la pile et le
transfre dans AX.

Djamal Rebane

88

Utilisation de la pile sur un exemple


Dans l'exemple suivant, que l'on
imaginera au milieu d'un programme, on
stocke les valeurs contenues dans AX et
BX pour pouvoir utiliser ces deux
registres, puis une fois l'opration
accomplie on remet les valeurs qu'ils
contenaient prcdemment...

Djamal Rebane

89

PUSH AX
PUSH BX
MOV AX, [0140]
ADD BX, AX
MOV [0140], BX
POP BX
POP AX

Djamal Rebane

90

Les registres SS et SP Les registres SS et SP


sont deux registres servant grer la pile:
SS (Stack Segment, dont la traduction est
segment de pile) est un registre 16 bits
contenant l'adresse du segment de pile courant.
Il doit tre initialis au dbut du programme
SP (Stack Pointer, littralement pointeur de pile)
est le dplacement pour atteindre le sommet de
la pile (16 bits de poids faible).

Djamal Rebane

91

SP pointe vers le sommet, c'est--dire sur le


dernier bloc occup de la pile. Lorsque l'on
ajoute un lment la pile, l'adresse contenue
dans SP est dcrmente de 2 octets (car un
emplacement de la pile fait 16 bits de longueur).
En effet, lorsque l'on parcourt la pile de la base
vers le sommet, les adresse dcroissent.
Par contre l'instruction POP incrmente de 2
octets (16 bits) la valeur de SP.

Djamal Rebane

92

PUSH: SP <- SP - 2
POP: SP <- SP + 2
Ainsi, lorsque la pile est vide SP pointe
sous la pile (la case mmoire en-dessous
de la base de la pile) car il n'y a pas de
case occupe. Un POP provoquera alors
une erreur...
Djamal Rebane

93

Dclarer une pile


Pour pouvoir utiliser une pile, il faut la dclarer,
c'est--dire rserver un espace mmoire pour
son utilisation, puis initialiser les registres avec
les valeurs correspondant la base de la pile,
ainsi que son sommet (rappel: situ sous la pile
lorsque celle-ci est vide).
Ainsi pour dfinir une pile, il s'agit tout d'abord
de la dclarer grce la directive SEGMENT
stack.
Djamal Rebane

94

Dclaration d'une pile


Pour utiliser une pile en assembleur, il faut dclarer un segment de pile, et y
rserver un espace suffisant. Ensuite, il est ncessaire d'initialiser les
registres SS et SP pour pointer sous le sommet de la pile. Voici la dclaration
d'une pile de 200 octets :
segment_pile SEGMENT stack ; mot clef stack pour pile
DW 100 dup (?) ; rserve espace
base_pile EQU this word ; etiquette base de la pile
segment_pile ENDS
Noter le mot clef ``stack '' aprs la directive SEGMENT, qui indique
l'assembleur qu'il s'agit d'un segment de pile.
Afin d'initialiser SP, il faut reprer l'adresse du bas de la pile; c'est le rle de la
ligne base_pile EQU this word (voir figure suivante).

Djamal Rebane

95

Djamal Rebane

96

Suite aux dclarations, il faut crire une


squence d'initialisations:

ASSUME SS:segment_pile; gnre une adresse pour lemplacement de la


; pile
MOV AX, segment_pile
MOV SS, AX ; initialise le segment de pile
MOV SP, base_pile ; copier l'adresse de la base de la pile dans SP

Remarquez quil n'est pas possible de faire


directement MOV SS, segment_pile car cette
instruction n'existe pas!

Djamal Rebane

97

Les procdures-fonctions
La notion de procdure - fonctions
En langage assembleur, on appelle procdure un sousprogramme qui permet d'effectuer un ensemble
d'instructions par simple appel de la procdure. Cette
notion de sous-programme est gnralement appele
fonction dans d'autres langages. Les fonctions et les
procdure permettent d'excuter dans plusieurs parties
du programme une srie d'instruction, cela permet une
simplicit du code et donc une taille de programme
minimale. D'autre part, une procdure peut faire appel
elle-mme, on parle alors de procdure rcursive (il ne
faut pas oublier de mettre une condition de sortie au
risque sinon de ne pas pouvoir arrter le programme...).
Djamal Rebane

98

Djamal Rebane

99

La dclaration d'une procdure


Etant donne qu'une procdure est une suite d'instructions, il s'agit de
regrouper les instructions composant la procdure entre des mots
cls. L'ensemble de cette manipulation est appele dclaration de
procdure.
Ces mots cls permettant la dclaration de la procdure sont le une
tiquette (qui reprsente le nom de la fonction) prcdant le mot clef
PROC marquant le dbut de la procdure, suivi de near (qui signale
que la procdure est situe dans le mme segment que le
programme appelant) et RET dsignant la dernire instruction, et
enfin le mot-cl ENDP qui annonce la fin de la procdure. Ainsi une
dclaration de procdure ressemble ceci:

Djamal Rebane

100

Etiquette PROC near


instruction1
instruction2
...
RET
Etiquette ENDP

Djamal Rebane

101

Appel d'une procdure


C'est l'instruction CALL qui permet l'appel d'une
procdure. Elle est suivie soit d'une adresse 16
bits, dsignant la position du dbut de la
procdure, ou bien du nom de la procdure
(celui de l'tiquette qui prcde le mot cl
PROC).

Djamal Rebane

102

Comment l'appel et la fin de la procdure fonctionnent? Lorsque


l'on appelle une procdure, la premire adresse de la procdure est
stock dans le registre IP (pointeur dinstruction), le processeur
traite ensuite toutes les lignes d'instructions jusqu' tomber sur le
mot cl RET, qui va remettre dans le registre IP l'adresse qui y tait
stock avant l'appel par PROC.
Cela parat simple mais le problme provient du fait que les procdures
peuvent tre imbriqus, c'est--dire que de saut en saut, le
processeur doit tre capable de revenir successivement aux
adresses de retour. En fait, chaque appel de fonction via
l'instruction CALL, le processeur empile l'adresse contenue dans le
registre IP (il pointe alors sur l'instruction suivant l'instruction CALL)
avant de la modifier, l'appel de l'instruction RET (qui ne prend pas
d'arguments) le contenu de la pile est dpil puis stock dans le
registre IP.
Djamal Rebane

103

Djamal Rebane

104

Voici un exemple dutilisation des procdures aussi


simple que possible : ce programme appelle 12
fois une procdure qui crit un message
lcran et rend la main au DOS.
Remarque : Les codes ASCII 10 et 13
reprsentent respectivement la fin de ligne et le
retour chariot. Grce eux, on revient la ligne
chaque fois quon a crit le message.

Djamal Rebane

105

Title les procdures


Pile segment stack
dw 100 dup (?)
Basedepile equ thisword
Pile ends
data segement
message db bonjour, monde!, 10,13, $
data ends
code segment
assume cs:code, ds:code, ss:pile
debut:
MOV AX, data
MOV DS, AX
MOV AX, Pile
MOV SS, AX ; initialise le segment de pile
MOV SP, basedepile
MOV CX,12
boucle: call ecritmessage
LOOP boucle

; appel de procdure
; dcrementer CX de une unit et aller
; boucle si CX est diffrent de 0

; terminer le programme ici par le retour au DOS


mov AX, 4C00h
INT 21H

Djamal Rebane

106

ecritmessage proc near ;notre fonction


mov ah, 09h
move dx,offset message
int 21h
ret
ecritmessage endp ; fin de la procdure/fonction
code ends ; fin du segment de code
end debut ; fin de la porte dentre

Djamal Rebane

107

Le passage de paramtres
Une procdure effectue gnralement des actions sur des donnes
qu'on lui fournit, toutefois dans la dclaration de la procdure il n'y a
pas de paramtres (dans des langages volus on place
gnralement les noms des variables comme paramtres entre des
parenthses, spars par des virgules). Il existe toutefois deux
faons de passer des paramtres une procdure:
Le passage des paramtres par registre: on stocke les valeurs dans
les registres utiliss dans la procdure
Le passage des paramtres par pile: on stocke les valeurs dans la
pile avant d'appeler la procdure, puis on lit le contenu de la pile
dans la procdure.
Le passage de paramtres par registres C'est une mthode simple
pour passer des paramtres: Elle consiste crire une procdure en
faisant rfrence des registres dans les instructions, et de mettre
les valeurs que l'on dsire dans les registres juste avant lappel de la
fonction...
Djamal Rebane

108

Le passage des paramtres par registre


Cette manire de procder est trs simple mettre en oeuvre mais
elle est trs limit, car on ne peut pas passer autant de paramtres
que l'on dsire, cause du nombre limit de registres. On lui
prfrera le passage des paramtres par pile.

Le passage de paramtres par pile


Cette mthode de passage de paramtres consiste stocker les
valeurs des paramtres dans la pile avant l'appel de procdure
(grce l'instruction PUSH), puis de lire le contenu de la pile grce
un registre spcial (BP: Base pointer) qui permet de lire des
valeurs dans la pile sans les dpiler, ni modifier le pointeur de
sommet de pile (SP).

Djamal Rebane

109

L'appel de la procdure se fera comme suit:


PUSH parametre1 ; o parametre1 correspond une valeur ou
une adresse
PUSH parametre2 ; o parametre1 correspond une valeur ou
une adresse
CALL procedure
La procdure commencera par l'instruction suivante:
MOV BP, SP ;permet de faire pointer BP sur le sommet de la
pile
Puis pourra contenir des instructions du type:
MOV AX, [BP] ;Stocke la valeur contenue dans le sommet de
;la pile dans AX, sans dpiler
MOV BX, [BP+2] ;Stocke la valeur contenue dans le mot
suivant de la
;pile dans BX (un mot fait 2 octets), sans
dpiler

Djamal Rebane

110

Exemple avec passage par


registre
On va crire une procdure ``SOMME'' qui
calcule la somme de 2 nombres naturels
de 16 bits.
Convenons que les entiers sont passs
par les registres AX et BX, et que le
rsultat sera plac dans le registre AX.
La procdure s'crit alors trs
simplement :
Djamal Rebane

111

SOMME PROC near ;


AX <- AX + BX
ADD AX, BX
RET
SOMME ENDP
et son appel, par exemple pour ajouter 6 la variable Truc :
MOV AX, 6
MOV BX, Truc
CALL SOMME
MOV Truc, AX

Djamal Rebane

112

Exemple avec passage par la pile

Cette technique met en oeuvre un nouveau registre, BP (Base Pointer), qui permet de lire
des valeurs sur la pile sans les dpiler ni modifier SP.
Le registre BP permet un mode d'adressage indirect spcial, de la forme :
MOV AX, [BP+6]; cette instruction charge le contenu du mot mmoire d'adresse BP+6
dans AX.
Ainsi, on lira le sommet de la pile avec :
MOV BP, SP
;BP pointe sur le sommet
MOV AX, [BP]
;lit sans dpiler et le mot suivant avec :
MOV AX, [BP+2]
;2 car 2 octets par mot de pile.

L'appel de la procdure ``SOMME2'' avec passage par la pile est :


PUSH 6
PUSH Truc
CALL SOMME2
Djamal Rebane

113

passage de paramtres
push AX
push BX
push CX
push DX
call soubroutine
; .........

; branchement vers la procdure


Contineur traitement

soubroutine proc near


mov BP,SP
; pointe vers le sommet de pile
move AX, [BP+2] ; acqurir dernier paramtre (DX) sans dpiler; pourquoi?
move AX, [BP+4] ; acqurir 3me paramtre (CX) sans dpiler
move AX, [BP+6] ; acqurir 2me paramtre (BX) sans dpiler
move AX, [BP+8] ; acqurir premeir paramtre (AX) sans dpiler
...........
ret
soubroutine ends

Djamal Rebane

114

Emplacement de sous-programmes
En gnral, les sous-programmes sont mis la fin
du programme principal. Mais, on peut aussi les
mettre dans la partie du segment de code.
Seulement,il faudra sassurer que la premire
instruction de code excute soit celle du
programme principal. Pour cela, il suffit juste de
mettre un JMP juste avant la dclaration du
sous-programme.

Djamal Rebane

115

Exemple: le calcul de PGCD de plusieurs nombres


TITLE PGCDdeplusieursnombres
SPILE SEGMENT STACK
DW 100 DUP(?)
SPILE ENDS
SDATA SEGMENT
valeurs DB 10,30,40,76,32,52
resultat DB 3 dup(?)
tab_sortie db 7 dup('$')
tab_conv db 7 dup('$')
start dw 0
SDATA ENDS
SCODE SEGMENT
ASSUME CS:SCODE,DS:SDATA
JMP debut
PGCD proc near ; dclaration de la fonction
repet:
MOV AL,CL
MOV AH,0
IDIV CH;
CMP AH,0
JE dfin
MOV CL, CH
MOV CH, AH
JMP repet
dfin:
RET
;le PGCD est dans CH
PGCD ENDP
;fin de la procdure PGCD

Djamal Rebane

116

DEBUT:
mov ax,sdata
mov ds,ax
mov SI,0; sert dindice tableau
MOV BX, 5; compteur de nombre manipuler
mov CH, valeurs[SI]
INC SI
repeter:
CMP BX,0
JE fin
mov CL, valeurs[SI]
Call PGCD
INC SI
DEC BX
JMP repeter
Fin: ; le PGCD de tous les nombres est dans CH

Djamal Rebane

117

xor ax,ax
; tout ce qui suit sert afficher les chiffres contenus dans le PGCD qui est dans CH
mov al,ch
mov si, offset tab_conv
mov start, offset tab_conv ;start sert garder le dbut du tableau
mov bx,0
mov bl,10
division:
; on suppose que la division se fait sur des nombre de 16 bits
div bl
cmp al,0
je fin_div
add ah,48
mov byte ptr[si],ah
mov ah,0
inc si
jmp division
fin_div:
add ah,48
mov byte ptr[si],ah
; tab_conv contient le nombre converti lenvers
xor bx,bx
mov bx, offset tab_sortie
xor ax,ax

Djamal Rebane

118

st_bcl:
cmp si,start
jb fin_bcl
mov ah , byte ptr[si]
mov byte ptr[bx] , ah
dec si
inc bx
jmp st_bcl
fin_bcl:
mov byte ptr[bx],10
inc bx
mov byte ptr[bx],13
inc bx
mov byte ptr[bx],'$'
mov dx,offset tab_sortie
mov ah,09h
int 21h
Sortie: MOV AX, 4c00h;
Int 21h
SCODE ENDS
END DEBUT

Djamal Rebane

119

Le compilateur se chargera alors de la


remplacer par les instructions comprises entre la
premire et la dernire ligne de cet exemple, en
prenant le soin de remplacer le mot chaine par
le message fourni en paramtre.
Supposons prsent que lon veuille crire
lcran le message Je suis bien content et
revenir la ligne laide de notre macro affiche
La syntaxe suivante :
affiche Coucou ! Ceci est un essai !, 10, 13, $

Djamal Rebane

120

Traitement des tableaux et


chanes de caractres
Une chane de caractres ASCII est constiue dune suite de caractres
termine par le $. Ce type de caractres est utilis par le MS DOS. Une
chane de caratres ASCII se dclare laide de la directive DB
Exemple:
mesg DB bonjour$
Message DB 'Bonjour$' est la mme chose que
Message DB 'B', 'o', 'n', 'j', 'o', 'u', 'r', '$' ou que
Message DB 66, 111, 110, 106, 111, 119, 114, 36
La seule obligation est le caractre '$' qui indique la fin de la chane (sinon
les octets situs la suite du message en mmoire sont aussi affichs
comme caractres).
Zone DB 30 DUP(?), $; chane de 30 caratres de valeur non dfinie
Tamp DB 25 DUP ( ); chane de 25 espaces blancs
Ligne DB 10 dupl( ); *, 20 dup (?), $
Djamal Rebane

121

En assembleur, il nexiste pas de distinction entre une chane de


caractres et un tableau de caractres. Ainsi, il est posible
daccder un lment quelconque de la chane.

;AL zone[i]; i >= 0


mov SI, i
mov AL, zon[SI]
;Zone[i] AL; i >= 0
mov DI, i
mov zone[DI], AL

Remarque: Les registres SI, DI, BX peuvent tre utiliss indiffrement pour
accder aux lments dune chane.

Djamal Rebane

122

Exemple de parcours squentiel dune chane

;AX nombre de lettres L


; SI registre dindex
mov SI,0
MOV AX, 0
While1: CMP zone[SI], $; tester la fin de la chane le $
JA enwhile1
If1:
CMP zone[SI], L
JNE endif1
INC AX
Endif1:
INC SI
JMP while1
Endwhile1:
Djamal Rebane

123

Autre possibilit: utiliser SI comme pointeur


lea SI,zone; SI contient ladresse de dbut de zone
MOV AX, 0
While1: CMP byte PTR [SI], $; tester si la fin de la chane est atteint
JA enwhile1
If1:
CMP byte PTR [SI], L
JNE endif1
INC AX
Endif1:
INC SI
JMP while1
Endwhile1:

Djamal Rebane

124

Les vecteurs
Vecteur dentiers
Le principe est le mme pour un vecteur dentiers o chaque lment
est stock sur un entier. Pour un vecteur dentiers stocks sur deux
octets nous devons tenir compte de la longueur dun lment du
vecteur.
Exemple:
T
T1

dw 1, 4, 7,-1; vecteur de 4 entiers initialiss respectivement


; aux valeurs 1, 4, 7 et -1
dw 100 dup (?); vecteur de 100 lments non initialiss.

Djamal Rebane

125

Implmentation en mmoire (un lment est sur 2 octets)


Indice
Dplacement
t

1
2
3
4
0 1
2 3
4 5
67
|--------------------------------------------|
|x x | x x | x x |
xx |
---------------------------------------------

Fonction dindicage: adresse de dbut de t


+ i * longueur dun lment de t
----------------------------------------------adresse du i me lment de t
Djamal Rebane

126

Exemple:

; AX t[i]
mov SI,i
ADD SI,SI; SI = SI * 2 (longeur dun lment)
MOV AX, t[SI]

; t[i] AX
MOV SI, i
ADD SI, SI
MOV t[SI], AX

Djamal Rebane

127

Tableau deux dimensions


La fonction dindicage des tableaux deux dimensions est plus
complexe. Gnralement, ces derniers sont rangs en mmoire
ligne par ligne.
Exemple:
Ligne 1 x x x x x x x x
Ligne 2 x x x x x x x x
Ligne 3 x x x x x x x x
Implmentation em mmoire
Ligne 1
ligne 2
ligne 3
xx xx xx xx xx xx xx xx xx xx xx xx
0 1

4 5

6 7

8 9

10 11 12 13 15 16 17 18 19 20 21 22 23 24

Djamal Rebane

128

Soit n et m le nombre de lignes et de colonnes, respectivement; et


i et j les indices de ligne et de colonne:
Adresse de dbut du tableau t
+
i * m longueur dun lment de t (slection de la ligne)
+
j * longueur dun lment de t
(slection de la colonne)
-------------------------------------------------------------= addresse de llment t[i][j]

Djamal Rebane

129

Exemple 8 : parcours d'un tableau


Ce programme passe une chane de caractres en majuscules. La fin de la chane est repre par
un caractre $. On utilise un ET logique pour masquer le bit 5 du caractre et le passer en
majuscule (voir le code ASCII).
Title parcours
pile
segment stack
100 dup (?)
pile ends
data
SEGMENT
tab DB 'Un boeuf Bourguignon', '$'
data
ENDS
code
SEGMENT
ASSUME DS:data, CS:code
debut:
MOV AX, data
MOV DS, AX
MOV BX, offset tab ; adresse debut tableau
repet:
MOV AL, [BX]
; lit 1 caractre
AND AL, 11011111b ; force bit 5 zero
MOV [BX], AL
; range le caractre
INC BX
; passe au suivant
CMP AL, '$'
; arrive au $ final ?
JNE repet
; sinon recommencer
MOV AH, 4CH
INT 21H
; Retour au DOS
code
ENDS
END debut
Djamal Rebane

130

Les instructions de traitement


de chanes de caractres
Les instructions disponibles pour effectuer des traitement de chaines
sont comme ci-desous. Ce jeu dinstructions permet de considrer
des chanes de caractres (1 octet) et de mots (2 octets).
MOVS
SCAS
CMPS
LODS
STOS

recopier des chanes


chercher un lment (octet, mot) dans une chane
comparer deux chanes
charger un lment dans le registre accumulateur
ranger le registre accumulateur dans une chane

Les instructions de chanes fonctionnent toutes selon le mme


principe:
Djamal Rebane

131

1.

2.
3.

4.

Le flag de direction du registre des codes-conditions indique le


sens de traitement de chaines: sil vaut zro, les chanes sont
traites par adresse croissante, sinon les chanes sont traites
par adresse dcroissante. Rappelons que linstruction CLD
initialise le flag de direction 0 que linstruction STD le positionne
1
Le nombre ditrations effectuer doit tre rang dans le registre
CX
Ladresse de dpart de la chane donne est dans lensemble des
registres DS et SI. Ladresse de dpart de la chane rsultat (ou
deuxime chane oprande) est dans le registre ES et DI
Choisir le prefixe et linstruction.

Djamal Rebane

132

Les prfixes disponibles sont:

REP ou REPZ rpte lopration du nombre de fois contenu dans


CX

REPE ou REPZ rpte lopration tant que lon a lgalit et que CX


est diffrent de 0

REPNE ou REPNZ rpte lopration tant que lon a diffrence et


que CX est diffrent de 0

Djamal Rebane

133

Rsum des instructions sur des chanes de caractres pour effectuer des oprations avec des
oprandes se trouvant dans des locations mmoire.
Instruction

Mnmonique

Destination

Source

Prfixe

Dep. Ch. Oct.

MOVSB

ES:DI

DS:SI

REP

Dep. Ch. Mot

MOVSW

ES:DI

DS:SI

REP

Sav. Ch. Oct.

STOSB

ES:SI

AL

REP

Sav. Ch. Mot

STOSW

ES:SI

AX

REP

Chg. Ch. Oct.

LODSB

AL

DS:SI

Chg. Ch. Mot

LODSW

AX

DS:SI

Cmp. Ch. Oct.

CMPSB

ES:DI

DS:SI

REPE/REPNE

Cmp. Ch. Mot

CMPSW

ES:DI

DS:SI

REPE/REPNE

Scn. Ch. Oct.

SCASB

ES:DI

AL

REPE/REPNE

Scn. Ch. Oct.

SCASW

ES:DI

AX

REPE/REPNE

DF(registreflag)Incrmentation(DF=0)Dcrmentation(DF=1)dupointeurutilispourlesoprations
CLD
DF=0
STD
DF=1
Djamal Rebane

134

Les instructions de gestion des chanes doctets


a) linstruction MOVSB ( Move String Byte )
Syntaxe : MOVSB
Description : Copie loctet adress par DS:SI
ladresse ES:DI. Si DF = 0, alors DI et SI sont
ensuite incrments, sinon ils sont
dcrments.
Remarque : Pour copier plusieurs octets, faire
REP MOVSB ( Repeat Move String Byte ). Le
nombre doctets copier doit tre transmis dans
CX de mme que pour un LOOP.
Exemple :

Djamal Rebane

135

Djamal Rebane

136

b) linstruction SCASB ( Scan String Byte )


Syntaxe : SCASB
Description : Compare loctet adress par ES:DI avec AL. Les
rsultats sont placs dans le registre des indicateurs. Si DF = 0,
alors DI est ensuite incrment, sinon il est dcrment.
Remarques : Pour comparer plusieurs octets, faire REP SCASB ou
REPE SCASB ( Repeat until Egal ), ou encore REPZ SCASB
( Repeat until Zero ). Ces trois prfixes sont quivalents.
Le nombre doctets comparer doit tre transmis dans CX. La
boucle ainsi cre sarrte si CX = 0 ou si le caractre point par
ES:DI est le mme que celui contenu dans AL (i.e. si ZF = 1). On
peut ainsi rechercher un caractre dans une chane.
Pour rpter au contraire la comparaison jusqu ce que ZF = 0,
cest--dire jusqu ce que AL et le caractre adress par ES:DI
diffrent, utiliser REPNE ou REPNZ.
Exemple :
Djamal Rebane

137

Djamal Rebane

138

c) linstruction LODSB ( Load String Byte )


Syntaxe : LODSB
Description : Charge dans AL loctet adress par DS:SI. Si DF = 0, alors SI est
ensuite incrment, sinon il est dcrment.
Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour
MOVSB.
d) linstruction STOSB ( Store String Byte )
Syntaxe : STOSB
Description : Stocke le contenu de AL dans loctet adress par ES:DI. Si DF = 0, alors
DI est ensuite incrment, sinon il est dcrment.
Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour
LODSB.
e) linstruction CMPSB ( Compare String Byte )
Syntaxe : CMPSB
Description : Compare loctet adress par DS:SI et celui adress par ES:DI. Si DF
= 0, alors SI et DI sont ensuite incrments, sinon ils sont dcrments.
Remarque : Possibilit dutiliser les prfixes de rptition, de mme que pour
SCASB.

Djamal Rebane

139

Exemple: REP

MOVSB et CLD

TITLE
PROG3_12.asm
;Transfert un bloc de 20 octets dans la mmoire
pile segment stack
dw 100 dup (?)
pile ends
data segment
DATA_S
DB
AQWERTTYUIOPLJKHGFDS
DATA_D
DB
20 DUP(?)
data ends
Code segment
assume CS:Code, ES:data, DS:data
MAIN
MOV AX,DATA
MOV DS,AX
; Initialiser le segment de donnes
MOV ES,AX
; Initialiser le segment Extra
CLD
; DF=0 Auto-incrmentation des pointeurs SI et DI
MOV SI,OFFSET DATA_S
; Charger le pointeur source
MOV DI,OFFSET DATA_D
; Charger le pointeur destination
MOV CX, 20
; Charger le compteur
REP
MOVSB; Dplacer les octets points par SI vers des locations points par DI
; et rpte jusqu CX 0, sachant qua chaque itration SI et DI sont
; automatiquement incrments
MOV AH,4CH
INT
21H
; DOS
Code ENDS
END MAIN

Djamal Rebane

140

TITLE Exemple:LODSB , REP STOSW et CLD


pile segment stack
dw 100 dup (?)
pile ends
data segment
DATA_S DB
AQWERTTYUIOPLJKHGFDS
DATA_D DB
20 DUP(?)
MESSAGE DB
Mmoire dfectueuse
ESP_MEM DB
100 DUP(?)
data ends
CODE segment
Assume CS:CODE, DS:data, ES: data
MAIN:
MOV AX,DATA
MOV DS,AX
; Initialiser le segment de donnes
MOV ES,AX
; Initialiser le segment Extra
CLD
; DF=0 Auto-incrmentation des pointeurs SI et DI
MOV CX, 50
; Charger le compteur avec 50 (50 mots = 100 octets)
MOV DI,OFFSET ESP_MEM
; Charger le pointeur destination
MOV AX, 0CCCCH
; le pattern qui servira de test
REP
STOSW
; Placer AAAAH dans 50 locations mmoires pointes par DI (jusqu CX0)
; sachant qua chaque itration DI est automatiquement incrment
MOV SI,OFFSET ESP_MEM
; Charger le pointeur source
MOV CX, 100
; Charger le compteur avec 100 (100 octets)
ENCORE: LODSB
; Charger de DS:SI vers AL (pas de REP)
XOR
AL, AH
; Est ce que le pattern est est le mme, sachant que dans AL et AH se trouve CCh
JNZ
PASSE
; Sortir du programme si cest diffrent mmoire dfectueuse
LOOP ENCORE
; continue jusqua CX0
JMP
SORTI
PASSE: MOV DX, OFFSET MESSAGE
; Afficher un message sur cran
MOV AH,09H
; le message est Mmoire dfectueuse
INT
21H
; DOS
SORTIR:MOV AH,4CH
INT
21H
; DOS
CODE ENDS
END MAIN

Djamal Rebane

141

Exemple:
REPE CMPSB et CLD
TITLE
PROG11.asm; Vrifier lorthographe dun mot et afficher un message
PILE SEGMENT stack
DW 100 DUP (?)
PILE ENDS
Data SEGMENT
MOT_EXACT DB CHICOUTIMI
MOT_TAPEE DB
CIHCOUTIMI
MESSAGE1
DB
Lorthographe est juste , $
MESSAGE2
DB
Lorthographe est fausse , $
DATA ENDS
CODE SEGMENT
ASSUME CS:code, DS:data, ES: data
MAIN:
MOV AX,DATA
MOV DS,AX
; Initialiser le segment de donnes
MOV ES,AX
; Initialiser le segment Extra
CLD
; DF=0 Auto-incrmentation des pointeurs SI et DI
MOV SI,OFFSET MOT_EXACT
; Charger le pointeur source
MOV DI,OFFSET MOT_TAPEE
; Charger le pointeur destination
MOV CX, 10
; Charger le compteur avec 10 (10 lettres ou octets)
REPE CMPSB
; Rpter tant que les deux lettres soient gales ou C= 0.
;Si cest diffrent le programme sort de cette instruction. A noter
;qu chaque itration SI et DI sont automatiquement incrments.
JE
PASSE
; Si ZF=1 afficher le message 1 (galit)
MOV DX,OFFSET MESSAGE2
; Si ZF=0 afficher le message 2 (diffrence)
JMP AFFICHAGE
PASSE: MOV DX, OFFSET MESSAGE1
AFFICHAGE: MOV AH,09H ; le message est Mmoire dfectueuse
INT
21H
; DOS
CODE ENDS
END MAIN

Djamal Rebane

142

Exemple:

REPNE

SCASB et CLD

TITLE
PROG12.asm
; Balayer une chane de caractre et Remplacer une lettre particulire par une autre
Pile segment stack
dw 100 dup(?)
Pile ends
Data segment
CHAINE DB Mr. Gones , $
Data ends
Code segment
MAIN: assume CS:code, DS:Data, ES:Data
MOV AX,DATA
MOV DS,AX
; Initialiser le segment de donnes
;MOV ES,AX
; Initialiser le segment Extra
CLD
; DF=0 Auto-incrmentation des pointeurs SI et DI
MOV DI, OFFSET CHAINE
; Charger le pointeur destination ES:DI
MOV CX, 9
; Charger le compteur avec 9 (la taille de la chane de caractres)
MOV AL, G
; le caractre a scanner (balayer)
REPNE SCASB
; Rpter le balayage tant que les deux lettres ne sont pas gales ou jusqua C= 0.
JNE
PASSE
; Saut si ZF=0 afficher le message 1 (galit)
DEC DI
; Dcrmenter DI (a la lettre G) car entre autre DI sest automatiquement incrment
MOV BYTE PTR[DI], J
; Remplacer G par J
PASSE: MOV DX, OFFSET CHAINE
AFFICHAGE: MOV AH,09H
; le message correcte est affiche: Mr. Jones
INT
21H
; DOS
Code

ENDS
END MAIN

Djamal Rebane

143

Donnee SEGMENT
chaine1 db 2000 dup(?)
chaine2 db 100 dup(?)
Donnee ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:Donnee, ES:Donnee
MOV AX, Donnee
MOV DS,AX
MOV ES,AX
ENTREE:
; initialiser sens de transfert
CLD
; adresse croissante
;initialiser chaine1 avec 200 caractres A
MOV AL, A
; caractres de remplissage
MOV CX,2000 ; longueur de la chane
LEA DI,chaine1 ; DI recoit ladresse de chaine1
REP STOSB

Djamal Rebane

144

; afficher chaine1
MOV CX,2000
LEA SI,chaine1
MOV AH,2 ;fonction DOS affichage dun caractre
Boucle: LODSB
MOV DL,AL
INT 21H
LOOP Boucle
; recopier dans chaine2 les 100 premiers caractres de chaine1
MOV CX,100
LEA SI,chaine1
LEA DI,chaine2
REP MOVSB

Djamal Rebane

145

; rechercher un caractre dans une chane


MOV CX,100
LEA DI,chaine1
MOV AL,B
;caractre rechercher
REPNE SCASB
JNE non_trouve
MOV DL,O
JMP aff1
non_trouve:
MOV DL,N
aff1: MOV AH,2
INT 21H

Djamal Rebane

146

; comparer deux chanes


MOV CX,100
LEA SI,chaine1
LEA DI,chaine2
REPE CMPSB
JNE non_identique
MOV DL,O
JMP aff2
non_identique:
MOV DL,N
aff2:
MOV AH,2
INT 21H
MOV AX,4C00H
INT 21H
CODE ENDS
END ENTREE

Djamal Rebane

147

La rcursivit
Dfinition:
Une procdure est dite rcursive si, et
seulement si, elle fait appel elle-mme,
soit directement soit indirectement

Djamal Rebane

148

Fonctionnement dune fonction


rcursive
Cration dune pile pour la sauvegarde
entre autres des paramtres dappels de
la procdure et la ladresse de retour.

Djamal Rebane

149

Calculer le factoriel de n, not n!


Le problme est: Calculer le factoriel d'un
nombre entier donn en entre.
En entre: Nous avons n nombre entiers qui
sont plus grands ou gaux 0.
Sortie: Nous avons un nombre entier qui
reprsente le factoriel de n.

Djamal Rebane

150

Fonction principale
entier n nfact
lire n
si (n < 0) alors crire entre ngative: n
sinon
nfact
factoriel(n)
crire la factorielle de n est nfact

o factoriel satisfait le prototype

entier factoriel(entier)

Djamal Rebane

151

Fonction factoriel
int factoriel(entier n)
{
si (n < 1) retourner 1
retourner n * factoriel(n-1)
}

Djamal Rebane

152

Comment le faire en assembleur?


On a besoin dune pile!
En effet, chaque appel rcursif, la valeur du paramtre
n est sauvegarde dans la pile de travail.
Ce processus dempilement est rpt jusqu ce que le
paramtre actuel (de lappel) n atteigne la valeur un.
Cela correspond la fin de lexcution de la fonction
appelante.
Ensuite, commence le dpilement, et lexcution de la
prochaine instruction de la fonction appelante est
entame. Ce processus de dpilement est rpt
jusqu ce quon atteigne la valeur de dpart du
paramtre n.

Djamal Rebane

153

Cela se traduit par le programme assembleur suivant


TITLE factoriel
PILE segment stack
dw 100 dup(?)
Basdepile equ this word
PILE ends
Data segment
N dw 4
fact dw ?
Data ends
Code segment
assume CS:code, DS:Data, SS:Pile
Debut:
MOV AX,Data
MOV DS,AX
MOV AX,Pile
MOV SS, AX ; initialise le segment de pile
MOV SP, basdepile ; copier l'adresse de la base de la pile dans SP
mov BX,n; sauvegarde la valeur de n
mov ax,bx
call factoriel
Fin:

pop AX; le rsultat calcul par la fonction factoriel est dans AX


mov fact, AX
mov AX,4c00h
int 21h

Djamal Rebane

154

factoriel proc near


push ax
Continuer:
CMP AX,1
JLE dpiler; dplier jusqu ce n = 1
dec AX
push AX
JMP continuer
Depiler:
POP AX
POP CX
mul CX
Push AX
CMP BX,CX
Ja depiler
ret
factoriel endp ; fin de la procdure
code ends
end debut ; fin du programme code

Djamal Rebane

155

Você também pode gostar