Académique Documents
Professionnel Documents
Culture Documents
Niveaux de programmation
• Niveaux de programmation
circuit logiques 0/1
---------------------------------------------------------------------------------
unité de traitement micro-instructions
(UAL, chemins de données) = suite de 0/1
(Unité de commande) 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 mnémoniques
Djamal Rebaïne 2
Structure d’un programme
assembleur 8086
TITLE nom ; donner un nom au programme
PILE SEGMENT STACK ; déclaration d’un segment de pile
; dont le nom est pile
..........
..........
PILE ENDS ; fin de la déclaration de la pile
DONNEE SEGMENT ; déclaration d’un segment de données qui va
; contenir les variables
...........
DONNEE ENDS ; fin de la déclaration de données
LECODE SEGMENT ; déclaration du segment de code qui va contenir
; le code
Debut: ; étiquette d’indication du point d’entrée du code
.................................
LECODE ENDS ; fin de la déclaration du code
END Debut ; fin du point d’entrée du code
Djamal Rebaïne 3
Exemple
TITLE prog2.asm: Exemple sur ROL,
Pile segment stack ;
dw 100 dup(?)
Pile ends
DATA segment
DATA1 DW 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 préfère)
JNC PROCHAIN ; Test si CF=0
INC BL ; Si CF = 1, incrémenter le compteur du nombre de ‘1’
PROCHAIN: DEC DL ; répéter 16 fois
JNZ ENCORE ; encore une fois si ce n’est pas fini
MOV COMPTE, BL ; sauvegarder le résultat dans la case mémoire COMPTE
En pratique aujourd'hui
- Permet de séparer clairement des zones mémoires selon
leur rôle
Djamal Rebaïne 5
Suite
Adressage sur 20 bits avec 2 registres
2 registres 16 bits : peut coder adresses sur 32 bits
Pour uniquement 20 bits
- Décale le premier registre de 4 bits et l'additionne au
second
- Adresse notée A:B
- Adresse réelle : A * 16 + B
Exemple (les nombres sont en hexa)
• 3100:27EE correspond à l'adresse 31000 + 27EE = 337EE
• Décaler de 4 bits en binaire revient à décaler d'un chiffre
en hexa
Djamal Rebaïne 6
Suite 2
Nous avons 4 segments d'adresses : CS, DS, SS, ES
• utiliser 2 registres pour adresser des mots mémoires
- Le premier est le registre de segment
- Le second un registre général
On l'appelle l'offset (décalage)
Addresse : segment:offset
• Exemples
- CS:IP : adresse de la prochaine instruction à exécuter
- DS:SI : adresse d'une donnée
- SS:SP : adresse du haut de la pile
Djamal Rebaïne 7
• Vos programme sources, écrits en
assembleur, doivent avoir l’extension
Djamal Rebaïne 8
Déclaration de variables
Les variables se déclarent de la manière suivante:
datas1 db ? ; datas1 est un byte non initialisé
datas2 db 0FFh ; datas2 est un byte initialisé à FF (255 en hexadécimal)
datas3 dw ? ; datas3 est un word (16 bits)
datas4 db 5 dup (?) ; datas4 est un tableau de 5 bytes non initialisés
datas5 dw 10 dup (15) ; datas5 est un tableau de 10 byte initialisés à 15
De manière générale:
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:
- décimal: 1, 2, 3, 123, 45
- hexadécimal : 1h,2h,3h,12h,0Fh,0AD4h (noter la présence du 0 quand le le premier
chiffre du nombre en hexadécimal commence par une lettre)
- binaire : 1b,0b,1010b,111101b
Djamal Rebaïne 9
Les entrées Sorties en assembleur
• Pour réaliser les opérations standards (affichage, saisie), le système
d’exploitation (ici DOS) fournit les fonctions pré-écrites suivantes:
• Affichage d’un caratère: mov DL, “A”; caractère A est transfére dans DL
mov AH, 2; fonction no. 2
int 21h ; appel au DOS
Djamal Rebaïne 10
• Saisie d’un caractère mov AH, 7; fonction no. 7
(sans écho) int 21h ; résultat dans AL
Djamal Rebaïne 11
L’équivalent de quelques instructions du langage
C en assembleur
Djamal Rebaïne 12
Instruction i
FAUX VRAI
…
Instruction i Condition ?
Si condition alors
Instructions j
Sinon
Instruction m Instructions m Instructions j
Fin si
Instructions k
Instructions k
Djamal Rebaïne 13
• La boucle FOR Assembleur
• For (k=0; k<=10; k++) MOV BX,0
• bx = bx + k; MOV CX,0
For: CMP CX,10
JA Endfor
ADD BX,CX
INC CX
JMP For
Endfor:
Djamal Rebaïne 14
• WHILE Assembleur
• bx = 5 MOV BX,5
• while (bx >0) while: CMP BX,0
bx = bx -1; JLE Endwhile
DEC BX
JMP while
Endwhile:
Djamal Rebaïne 15
• SWITCH Assembleur
• switch (n) { CMP n,1
case 1: ....; break; JNE case2
case 2: .....; break; ............
default: .....; JMP endswitch
} case2: CMP n,2
JNE default
..........
JMP endswitch
default: ...........
endswitch: ...........
Djamal Rebaïne 16
Écrire le code de l’instruction En assembleur
if (a>b) && (c <= d) if: cmp a, b
{ jng endif
................
} cmp c, d
jnle endif
..............
endif:
} }
Djamal Rebaïne 17
Liste des registres les plus utilisés
A. Registres généraux
• AX (A pour accumulateur): joue le rôle d’opérande implicite dans
plusieurs opérations: MUL, DIV, INC, etc.
• CX (C pour compteur): est utilisé pour les boucles (instruction
LOOP).
• DX: utilisé dans les multiplications et divisions comme registre
d’extension.
• SI (Source Index): souvent utilisé comme pointeur sur une adresse
mémoire (exemple: MOV AL, [SI]). Il est très utilisée avec les
instructions de traitement de chaînes de caractères (LODS).
• DI (Destination Index): pareil que SI (instruction STOS)
• BP (base pointeur): sert de pointeur sur la base de la pile, et permet
d’atteindre n’importe quel élément 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 Rebaïne 18
B. Registres spéciaux
• IP (Instruction pointeur): contient l’adresse de l’instruction qui suit
celle qui est en cours d’exécution.
• DS (Data Segment): Pointe sur le début du segment qui contient
les données
• CS (Code Segment): Pointe sur le segment qui contient le code du
programme.
• ES (Extended Segment) : permet de pointer sur un segment
supplémentaire défini par le programmeur. Il se charge par
l’intermédiaire de AX, comme pour DS.
• SS (Stack Segment): segment contenant la pile.
Djamal Rebaïne 19
Djamal Rebaïne 20
Format standard d’une instruction
Label: Mnémonique Opérandes ;commentaire
Djamal Rebaïne 21
• Mnémonique (des instructions): il sert à
identifier une instruction donnée. Quelques
instructions de base sont résumées dans la
prochaine section.
• Opérandes: une instruction assembleur peut
avoir de 0 à 3 opérandes. Chaque opérande
peut être le nom d’un registre, un opérande
mémoire, une expression constante ou le nom
d’un périphérique entrée/sortie.
• Commentaire: précédé du point-virgule (;). Il
sert à à ajouter des informations explicatives au
sujet du fonctionnement du programme ou de
l’instruction correspondante.
Djamal Rebaïne 22
Quelques instructions de base-1
• Affectations
; Registres <-- Valeurs
MOV AX, 65535 ; (décimal)
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 Mémoire
Mov AX, Offset variable ; AX <- adresse de variable
Mov CX, [ 5Ah ] ; CX <- valeur à l'adresse 5A en hexa
Djamal Rebaïne 23
Quelques instructions de base- 2
• Arithmétique
; Incrémentation
INC AX ; AX <- AX + 1
Inc ma_variable
; Décrémentation
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 Rebaïne 24
Quelques instructions de base-3
• Logique
; AND bit à bit
MOV AH, 0101b ; AH <- 5
MOV BH, 1001b ; BH <- 9
AND AH, BH ; AH <- AH AND BH; AH vaut 0001b, soit 1
; OR bit à bit
MOV AH, 0101b ; AH <- 5
MOV BH, 1001b ; BH <- 9
Or AH, BH ; AH <- AH OR BH; AH vaut 1101b, soit 13 (8+4+1)
; XOR bit à bit
MOV AH, 0101b ; AH <- 5
MOV BH, 1001b ; BH <- 9
XOR Ah, BH ; AH <- AH XOR BH; AH vaut 1100b, soit 12 (8+4)
; NOT bit à bit
MOV AH, 0101b ; AH <- 5 Not AH ; AH <- NOT AH; AH vaut 1010b,
soit 10 (8+2)
Djamal Rebaïne 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 définir des labels (étiquettes): les endroits dans le programme où va sauter si
le test est vérifié (comme les GOTO en Fortran).
; Egalité (Jump if Equal)
CMP AX, 5
JE label_1
; Différence (Jump if Not Equal)
CMP AX, ma_variable
JNE label_2
;Inférieur, Supérieur, 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 Rebaïne 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
Djamal Rebaïne 27
Djamal Rebaïne 28
JZ Saut si zéro. JNZ
JE Saut si égal. ZF = 1 JNE
JC Saut si Retenue (inférieur). JNC
JB Saut si inférieur. JNB
JNAE Saut si ni supérieur ni égal. CF = 1 JAE
JS Saut si signe négatif. SF = 1 JNS
JO Saut si débordement. OF = 1 JNO
JPE Saut si parité paire.
JP Saut si parité. PF = 1 JPO
JNZ Saut si pas zéro. JZ
JNE Saut si différent. ZF = 0 JE
JNC Saut si pas de retenue. JC
JNB Saut si pas inférieur. JB
JAE Saut si supérieur ou égal. CF = 0 JNAE
JNS Saut si aucun signe (positif). SF = 0 JS
JNO Saut si pas de débordement. OF = 0 JO
JPO Saut si parité impaire. JPE
Djamal Rebaïne 29
JNP Saut si pas de parité. PF = 0 JP
Modes d’adressage
Un mode d'adressage est un moyen qui permet au
microprocesseur d'avoir accès à une donnée.
Cette donnée peut être un nombre quelconque
dont on aura besoin dans le programme, un
nombre qui se trouve déjà dans un registre, ou
encore un nombre qui se trouve écrit quelque
part en mémoire.
• La connaissance des principaux modes
d'adressage est nécessaire car elle permet
d'écrire les programmes de la façon la plus
courte, la plus simple et la plus lisible possible.
Djamal Rebaïne 30
Modes d’adressage
• Mode immédiat
L’opérande est codée avec l’instruction
mov AX, 568
• Mode registre
L’opérande est un registre de donnée ou d’adresse
mov AX,BX
• Mode mémoire direct
L’opérande est désigné par l’adresse donnée dans l’instruction
mov [0hC040],AL
mov DS :[0hC040],AL
mov CS:var2,AX
mais pas
mov 0hFE15 :var2,AX
Djamal Rebaïne 31
Modes d’adressage pour
accéder aux données
• Mode mémoire indirect
L’opérande est désignée par une adresse placée dans les
registres d’adresses donnée dans l’instruction
mov AX,[SI] BX,BP,SI,DI peuvent servir de registre
pointeur
1. Indirect avec déplacement
L’adresse = contenu du registre d’adresse + déplacement
(le registre d’adresse n’est pas modifié)
mov AX, [DI]
mov BX,[DI+6]
Djamal Rebaïne 32
Modes d’adressage pour
accéder aux données
2. Indirect avec index
L’adresse = contenu du registre d’adresse
+ contenu du registre d’index (le registre
d’adresse n’est pas modifié)
mov [BP][DI],AX
les couples possibles sont BP-DI,
BP-SI, BX-DI, BX-SI
Djamal Rebaïne 33
Quelques notes utiles
• La déclaration d’une chaîne de caractères est mise en
'' '' ou ' ' .
• Le caractère '$' indique la fin d’une chaîne de caractères.
Son omission implique que les octets en mémoire qui
viennent après cette chaîne sont aussi affichés comme des
caractères.
• L’assembleur ne fait pas de différence entre une majuscule
et une minuscule dans l’écriture de ses instructions et la
notation des registres.
• La directive ASSUME permet d'indiquer à l'assembleur où
se situe le segment de données et le segment de code. Puis
il s'agit d'initialiser le segment de données à l’intérieur du
segment de code:
MOV AX, nom_du_segment_de_donnees
MOV DS, AX
Djamal Rebaïne 34
Un petit mot sur l’instruction
de transfert
MOV reg, reg (registre à registre)
reg, mem (registre à mémoire)
mem, reg (mémoire à registre)
reg, imed (registre à valeur)
mem, imed (mémoire à valeur)
Djamal Rebaïne 35
Applications de quelques
instructions sur des exemples
Djamal Rebaïne 36
Instruction CMP (Comparer) CMP destination, source Compar C ZF
e F
Opérand
L’instruction CMP affecte les indicateurs AF, OF, SF, PF, CF et ZF
es
mais seuls CF et ZF sont utilisés.
Dest. > 0 0
L’opérande destination peut être dans un registre ou dans une mémoire.
L’opérande source peut être dans un registre, dans une mémoire, ou en mode immédiat.
Src.
Les opérandes (destination et source) ne changent pas. Dest. = 0 1
Src.
DATA1 DW 235FH
… Dest. < 1 0
MOV BX, 7888H ; 7888Hh BX Src.
MOV CX, 9FFFH
CMP BX, CX ; BX < CX CF=1 JNC est exécutée PASSE
JNC PASSE ; Note: les contenus de (BX, et CX) ne changent pas après CMP
ADD BX, 4000H
PASSE: ADD CX, DATA1 ; mais CF est toujours vérifié pour (< ou >). Pour (=) on utilise ZF.
TEMP DB ?
…
MOV AL, TEMP ; TEMP AL
CMP AL, 99 ; TEMP = 99?. Avec (SUB AL, 99), la même chose mais 0 AL
JZ PROCHAIN ; Si ZF=1 (TEMP=99), Saute a PROCHAIN:
INC BX ; Sinon incrémente BX
PROCHAIN: HLT ; Arrêt du programme
Djamal Rebaïne 37
TITLE prog1.asm: Exemple sur CMP, Trouver l’octet le plus grand parmi 5 notes d’élèves
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 ; génération de l’adresse du segment de code et de données
MOV AX, DATA ; Initialiser le registre DS pour récupérer l’adresse du segment de donnée
MOV DS, AX
MOV CX, 5 ; compteur de boucle
MOV BX, OFFSET NOTES ; BX pointe vers les données NOTES
XOR AL, AL ; Initialise AL à 0; va héberger la plus grande note
ENCORE: CMP AL, [BX] ; compare la note prochaine a la note la plus élevée
JA PROCHAIN ; Sauter si AL est encore la note la plus élevée
MOV AL, [BX] ; sinon AL retient la plus élevée
PROCHAIN: INC BX ; pointe vers la prochaine note
LOOP ENCORE ; CX décrémente jusqu’à 0 pour sortir de la LOOP
MOV PLUS_G, AL ; sauvegarde de la note la plus élevée dans PLUS_G
;-------------------------------------------------------------------------------------------------------------------------------------------------------------
MOV AH, 4Ch
INT 21h
MAIN ENDS
END MAIN
Djamal Rebaïne 38
TITLE prog2.asm: Exemple sur ROL, Trouver le nombre de ‘1’ dans un mot
Pile segment stack ; déclaration d’un segment de pile – pas nécessaire dans notre cas
dw 100 dup(?)
Pile ends
;------------------------------------------------------------------------------------------------------------------------------------------------------------
DATA segment
DATA1 DW 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 préfère)
JNC PROCHAIN ; Test si CF=0
INC BL ; Si CF = 1, incrémenter le compteur du nombre de ‘1’
PROCHAIN: DEC DL ; répéter 16 fois
JNZ ENCORE ; encore une fois si ce n’est pas fini
MOV COMPTE, BL ; sauvegarder le résultat dans la case mémoire COMPTE
;------------------------------------------------------------------------------------------------------------------------------------------------------------
MOV AH, 4Ch
INT 21h
MAIN ENDS
END MAIN
Djamal Rebaïne 39
Quelques explications
L’itération: On peut également transcrire une boucle à l’aide de
l’instruction LOOP nécessitant l’utilisation implicite du registre CX.
MOV CX, unevaleur
Boucle:
…… ; le corps de la boucle
LOOP Boucle
Cela signifie que le corps de la boucle est exécuté tant que la valeur
de CX n’est pas nulle. A chaque itération, CX est décrémenté d’une
unité.
Attention: si CX est nul au premier tour, alors il décrémenté 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 Rebaïne 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 ; décrémente d’une unité CX.
; si CX > 0 fait le saut à for
Djamal Rebaïne 41
On peut aussi utiliser LOOPE/LOOPZ/LOOPNE/LOOPNZ
pour signifier :
Djamal Rebaïne 42
Buffer DB 8 DUP(0)
……..
Boucle:
Djamal Rebaïne 43
• Décalage et rotation
SHL (Shift Left; SHR: shift right): effectue un décalage à gauche des bits. Si le deuxième
opérande est une valeur, alors seule la valeur 1 est acceptée. Le bit de poids fort
se retrouve dans CF; un 0 est introduit dans le bit de poids faible.
SHL AL, 1
Une façon plus élégante consiste à utiliser CL dans son rôle de compteur:
MOV CL, 4
SHL AX,CX
Pareil pour les instructions SAR, ROR, RCR et leurs équivalents à gauche.
Djamal Rebaïne 44
Manipulation de données
1. Operateur offset: renvoie l’adresse à laquelle est située un label de donnée
Exemple: ……
Bval db ?
Wval1 dw ?
Wval2 dd ?
……
Si Bval se trouve à l’adresse offset 00404000 (hexa), l’opérateur offset renvoie les
valeurs suivantes:
MOV AX, offset bval ; AX = 00404000
MOV AX, offset Wval1 ; AX = 00404001
MOV AX, offset Wval2 ; AX = 00404002
Djamal Rebaïne 45
Un mot sur les macros
Djamal Rebaïne 46
Les macros, à la différence des procédures, n’ont aucune
signification pour la machine. Seul l’assembleur
comprend leur signification. Elles ne sont qu’un artifice
mis à la disposition du programmeur pour clarifier son
programme. Lorsque l’assembleur rencontre le nom
d’une macro dans votre code, il le remplace par le code
de la macro. Tout se passe exactement comme si vous
aviez tapé vous-même ce code à la place du nom de la
macro.
Djamal Rebaïne 47
Voici comment écrire une macro :
Djamal Rebaïne 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 Rebaïne 49
• L’assembleur se chargera alors de la remplacer
par les instructions comprises entre la première
et la dernière ligne de cet exemple, en prenant
le soin de remplacer le mot chaine par le
message fourni en paramètre.
• Supposons à présent que l’on veuille écrire à
l’écran le message « Coucou ! Ceci est un essai »
et revenir à la ligne à l’aide de notre macro
affiche
• La syntaxe suivante :
• affiche ‘Coucou ! Ceci est un essai !’, 10, 13, ‘$’
• 10, 13 est l’équivalent de endln en C-C++
Djamal Rebaïne 50
Présentation d’autres exemples
Djamal Rebaïne 51
TITLE ex3_somme; somme de deux nombres
PILE SEGMENT STACK; déclaration de pile.
; Pour cet exemple, la pile n’est pas nécessaire.
DW 100 DUP (?)
PILE ENDS
affiche macro chaine ; macro pour afficher une chaîne de
; caractères
MOV DX,offset chaine ; offset renvoie l’adresse de début de chaine
MOV AH, 09h ; fonction qui affiche une chaîne de caractères
INT 21h
ENDM; fin de la macro
Djamal Rebaïne 52
SCODE SEGMENT ; zone de code
ASSUME CS:SCODE, DS:DATA ; génération de l’adresse du segment de
code et de données
DEBUT: ; entrée du code
MOV AX, DATA ; Initialiser le registre DS pour récupérer l’adresse du
MOV DS, AX ; segment de donnée
Djamal Rebaïne 53
affiche aff_resu; appel de la macro pour afficher un message sur écran
SUB val2,30h ; les valeurs lues tantôt sont en ascii; exemple :
; si on tape les valeurs 1 et 2,
; le programme récupère 31 et 32, valeurs
; hexadécimales des caractères 1 et 2.
; Donc 31 + 32 = 63. et 63 n’est pas la valeur hexa
; du caractère 3. Sa valeur est 33
; autrement dit, on doit retirer 30 en hexa ou 48 en
; décimal.
MOV AH,2 ; afficher la valeur saisie grâce à 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 l’exécution s’est déroulée correctement.
; Équivalent en c de return 0
SCODE ENDS; fin du segment de code
END DEBUT
Djamal Rebaïne 54
TITLE ex4_max ; détermine et affiche le maximum de deux nombres
; introduits à travers le clavier
PILE SEGMENT STACK
DW 100 DUP (?) ; déclaration d’une pile de 100 éléments
PILE ENDS
affiche macro chaine ; à la compilation, l’assembleur recopie l’ensemble
; de instructions de cette macro
mov dx,offset chaine ; pointe vers le début de la chaîne chaine
mov ah, 09h ; pour afficher une chaîne de caractères à partir de
; l’adres de début 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,'$' ; $ caractère de fin de chaîne
DATA ENDS
Djamal Rebaïne 55
SCODE SEGMENT
ASSUME CS:SCODE, DS:DATA ; génération d,adresses pour les segments de code et de
données
DEBUT: ; entrée du code
; Initialiser le registre DS par l’adresse du segment de donnée générée par
; la directive ASSUME
MOV AX, DATA
MOV DS, AX
Djamal Rebaïne 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 l’entrée du code
Djamal Rebaïne 57
Exemple 5: que fait cette portion de code?
Djamal Rebaïne 58
Exemple 6 : que fait la portion de code ci-dessous ?
Djamal Rebaïne 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; déclaration 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,'$' ; $
caractère de fin de chaîne
DATA ENDS
Djamal Rebaïne 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 à l’aide 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 Rebaïne 61
• Exemple 7: Exemple sur ROL, Trouver le
nombre de ‘0’ dans un double-mot
Djamal Rebaïne 62
TITLE programme.asm: Exemple sur ROL, Trouver le nombre de ‘0’ dans un double-mot
PILE SEGMENT STACK
DW 100 DUP (?)
PILE ENDS
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 deuxième mot
ENCORE1: ROL AX, 1 ; Rotation à gauche (à droite aussi si on préfère)
JC PROCHAIN1 Test si CF=1
INC CL ; Si CF = 0, incrémenter le compteur du nombre de ‘0’
PROCHAIN1: DEC DL ; répéter 16 fois
JNZ ENCORE1 ; encore une fois si ce n’est pas fini
MOV AL, CL ; sauvegarder le résultat dans AL, en sortant de la boucle, le contenu de AX
; nous importe peu, donc en écrasant le premier mot n’est pas grave
ENCORE2: ROL BX, 1 ; Rotation à gauche
JC PROCHAIN2 ; Test si CF=1
INC CH ; Si CF = 0, incrémenter le compteur du nombre de ‘0’
PROCHAIN2: DEC DH ; répéter 16 fois
JNZ ENCORE2 ; encore une fois si ce n’est pas fini
MOV AH, CH; sauvegarder le résultat dans AH. Même remarque qu’en haut
ADD AH, AL ; Additionner les nombres de ‘0’ trouvés séparément dans les 2 mots
MOV COMPTE, AH ; et sauvegarder le résultat dans COMPTE
MOV AH, 4Ch ; retour au DOS
INT 21h
Code ENDS
END MAIN
Djamal Rebaïne 63
Conversion Minuscule en
Majuscule
Hex Hex
L Binaire L Binaire
A 41 01000001 a 61 01100001
B 42 01000010 b 62 01100010
. ………… . …………
. ………… . …………
Y 59 01011001 y 79 01111001
Z 5A 01011010 z 7A 01111010
Djamal Rebaïne 64
TITLE prog8.asm ; Conversion MINUSCULE MAJUSCULE d’un 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 caractère
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 caractère MAJUSCULE
INC SI ; incrémente le “pointeur vers le texte original”
INC BX ; incrémente 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 Rebaïne 65
Exemple 9: lit une chaîne de caractères et
l’affiche à l’envers
• Programme palin
Djamal Rebaïne 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 d’une chaîne de caractères
;qui se termine dès qu’on tape le retour chariot (touche entrée)
int 21h
mov si,dx
mov cx,si
Djamal Rebaïne 67
Deb: cmp BL,0dh; comparer à la touche entrée 13 en ascii car la fin de reponse contient ce caractère
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 Rebaïne 68
Une autre manière de le faire
• ;debut:
• xor dx,dx
• mov DL,[si+1] ; récupération du nombre de caractères lus
• ; la taille à récupérer est obtenue par l’objet de destination
• ; car [si+1] n’a pas de taille spécifique donc obligation de la
• ; récupérer avec la destination
• ; ici DL donc récupération de 8bits ; si DX récupération de 16bits
• ; la destination décide de la taille à récupérer
• 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 Rebaïne 69
Une troisième manière de le faire
• debut:
• xor DX,DX
• mov DX,reponse[si] ; récuperation du nombre de caractères lus
• ; la taille à récupérer est obtenue par l’objet de destination
• ; ici DL donc récupération de 8bits si DX récupération de 16bits
• ; la destination décide de la taille à récupérer
• 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 Rebaïne 70
• MULTIPLICATION ET DIVISION SIGNÉE (IMUL / IDIV) reg.
(ou mém.)
• Note: Dans les manuels d’Intel IMUL et IDIV pour Integer MULtiplication
et DIVision (X et / des nombres entiers) mais au fait il s’agit de
Multiplication et Division des nombres signées.
DIVISION SIGNEE NUM. (> ou <) DENOM. (> ou <) QUOTIENT RESTE
DoubleMot/Mot
Djamal Rebaïne 71
Title exemple pour trouver la moyenne d’un 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:
MOV CX,9 ; Charger le compteur
XOR BX,BX ; Mettre a 0 le registre BX, utilisé comme accumulateur
MOV SI,OFFSET SIGN_DAT ; SI SIGN_DAT
ARRIERE: MOV AL,[SI] ; Un octet de donnée AL
CBW ; Extension du signe AX
ADD BX,AX ; BX+AXBX
INC SI ; SI+1 SI
LOOP ARRIERE ; Boucler tant que CX > 0
MOV AL,9 ; Le nombre totales des températures AL
CBW ; Extension du signe AX
MOV CX,AX ; Sauvegarder le DENOMINATEUR dans CX
MOV AX,BX ; LA somme des températures AX
Djamal Rebaïne 72
Expression arithmétique
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 ;établir la constante
IMUL A ;DX:AX = A*2
MOV BX,DX ;
MOV CX,AX ;BX:AX = A *2
MOV AX,B
IMUL C ;DX:AX = B*C
ADD AX,CX ;AX = AX + CX ! faites attention, il peut y avoir une retenue ici
ADC DX,BX ;DX:AX = A*2+B*C + la retenue s’il y a lieu avec ADC
MOV CX, D
SUB CX,3 ; cx = D -3
IDIV CX ; AX =(A*2 + B*C)/(D-3)
MOV X,AX ; X = ax (A*2 +B*C)/(D-3) stocker le résultat
RET
Arithmetique endp ; fin de la procedure
............
Djamal Rebaïne 73
Conversion d’une chaine de caractères en
une valeur décimale
Toute information introduite via le clavier est
considérée comme une chaîne de
caractères. Ainsi, si on introduit le nombre
827, il sera considéré par l’assembleur
comme la chaîne de caractères ‘827’.
Pour avoir sa valeur numérique, il y a lieu
de la convertir suivant l’algorithme suivant:
Djamal Rebaïne 74
Algorithme de conversion
• nbre = nombre de caractère lus
• Nombre = 0
• Repeter
• chiffre = caractère lu
• nombre = nombre *10+chiffre
• nbre = nbre -1
• Si nbre > 0 aller à repeter
•
Djamal Rebaïne 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 Rebaïne 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, c’est pareil. C’est pour rendre le caractère lu comme une valeur numérique
mov DH,0
add AX,DX
inc SI
loop repeter
MOV AX,4C00H
INT 21H
SCODE ENDS
END DEBUT
Djamal Rebaïne 77
Pour lire une chaine de caractères, appeler 21h fonction 0Ah qui installe les
caractères tapés dans une zone repérée par DS:DX (buffer déclarée dans
le segment de données). La fonction se termine quand un return (touche
entréée) est détecté. Le buffer contient alors les informations suivantes:
byte contenu
0 nombre maximum de caractères à lire
Djamal Rebaïne 78
Conversion d’une valeur décimale en une
chaîne de caractères
Djamal Rebaïne 79
Algorithme
k=0
do
quotient = nombre / 10;
reste = nombre % 10;
tab[k] = reste;
nombre = quotient;
k++
while (quotient != 0)
Djamal Rebaïne 80
Dans ce programme, les chiffres composant le nombre contenu dans AX
est affiché dans le bon ordre
Djamal Rebaïne 81
fin_div:
add AH,48
mov byte ptr[si],AH
;tabconv contient le nombre converti à l’envers
xor BX,BX
mov BX, offset tabsortie ; à declarer dans le
segment de données
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 Rebaïne 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 Rebaïne 83
La directive EQU
La directive EQU a un rôle voisin de
celui des macros. Elle permet de
remplacer un simple mot par d’autres
plus complexes. Son intérêt est
qu’elle peut être invoquée en plein
milieu d’une ligne.
Djamal Rebaïne 84
Quelques exemples
Djamal Rebaïne 85
Les piles
Djamal Rebaïne 86
• Utilité d'une pile
Une pile est une zone de mémoire dans laquelle on peut stocker
temporairement des registres. Il s'agit d'un moyen d'accéder à des données
en les empilant, telle une pile de livre, puis en les dépilant pour les utiliser.
Ainsi il est nécessaire de dépiler les valeurs stocker au sommet (les
dernières à avoir été stockées) pour pouvoir accéder aux valeurs situées à
la base de la pile.
En réalité il s'agit d'une zone de mémoire et d'un pointeur qui permet de repérer
le sommet de la pile.
La pile est de type LIFO (Last In First Out), c'est-à-dire que la première
valeur empilée sera la dernière sortie (Si vous empilez des livres, il vous
faudra les dépiler en commençant par enlever les livres du dessus. Le
premier livre empilé sera donc le dernier sorti!).
Djamal Rebaïne 87
Ainsi, l'instruction
PUSH BX
empile le contenu du registre BX,
et l'instruction
POP AX
Djamal Rebaïne 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'opération accomplie on remet les
valeurs qu'ils contenaient
précédemment...
Djamal Rebaïne 89
• PUSH AX
• PUSH BX
• MOV AX, [0140]
• ADD BX, AX
• MOV [0140], BX
• POP BX
• POP AX
Djamal Rebaïne 90
• Les registres SS et SP Les registres SS et SP
sont deux registres servant à gérer la pile:
Djamal Rebaïne 91
• SP pointe vers le sommet, c'est-à-dire sur le
dernier bloc occupé de la pile. Lorsque l'on
ajoute un élément à la pile, l'adresse contenue
dans SP est décrémentée 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 décroissent.
Par contre l'instruction POP incrémente de 2
octets (16 bits) la valeur de SP.
Djamal Rebaïne 92
• PUSH: SP <- SP - 2
• POP: SP <- SP + 2
Djamal Rebaïne 94
Déclaration d'une pile
Pour utiliser une pile en assembleur, il faut déclarer un segment de pile, et y
réserver un espace suffisant. Ensuite, il est nécessaire d'initialiser les
registres SS et SP pour pointer sous le sommet de la pile. Voici la
déclaration d'une pile de 200 octets :
Noter le mot clef ``stack '' après la directive SEGMENT, qui indique à
l'assembleur qu'il s'agit d'un segment de pile.
Afin d'initialiser SP, il faut repérer l'adresse du bas de la pile; c'est le rôle de la
ligne base_pile EQU this word (voir figure suivante).
Djamal Rebaïne 95
Djamal Rebaïne 96
• Suite aux déclarations, il faut écrire une
séquence d'initialisations:
Djamal Rebaïne 97
Les procédures-fonctions
La notion de procédure - fonctions
En langage assembleur, on appelle procédure un sous-
programme qui permet d'effectuer un ensemble
d'instructions par simple appel de la procédure. Cette
notion de sous-programme est généralement appelée
fonction dans d'autres langages. Les fonctions et les
procédure permettent d'exécuter dans plusieurs parties
du programme une série d'instruction, cela permet une
simplicité du code et donc une taille de programme
minimale. D'autre part, une procédure peut faire appel à
elle-même, on parle alors de procédure récursive (il ne
faut pas oublier de mettre une condition de sortie au
risque sinon de ne pas pouvoir arrêter le programme...).
Djamal Rebaïne 98
Djamal Rebaïne 99
La déclaration d'une procédure
Etant donnée qu'une procédure est une suite d'instructions, il s'agit de
regrouper les instructions composant la procédure entre des mots
clés. L'ensemble de cette manipulation est appelée déclaration de
procédure.
Etiquette ENDP
Cela paraît simple mais le problème provient du fait que les procédures
peuvent être imbriqués, 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 dépilé puis stocké dans le
registre IP.
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 ; appel de procédure
LOOP boucle ; décrementer CX de une unité et aller à
; boucle si CX est différent de 0
MOV AX, 6
MOV BX, Truc
CALL SOMME
MOV Truc, AX
Cette technique met en oeuvre un nouveau registre, BP (Base Pointer), qui permet de lire
des valeurs sur la pile sans les dépiler ni modifier SP.
MOV AX, [BP+6]; cette instruction charge le contenu du mot mémoire d'adresse BP+6
dans AX.
PUSH 6
PUSH Truc
CALL SOMME2
push AX
push BX
push CX
push DX
call soubroutine ; branchement vers la procédure
; ......... Contineur traitement
• La syntaxe suivante :
• affiche ‘Coucou ! Ceci est un essai !’, 10, 13, ‘$’
Exemple:
mesg DB ‘bonjour$’
• Message DB 'Bonjour$' est la même 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 caractère '$' qui indique la fin de la chaîne (sinon
les octets situés à la suite du message en mémoire sont aussi affichés
comme caractères).
Remarque: Les registres SI, DI, BX peuvent être utilisés indifférement pour
accéder aux éléments d’une chaîne.
Vecteur d’entiers
Le principe est le même pour un vecteur d’entiers où chaque élément
est stocké sur un entier. Pour un vecteur d’entiers stockés sur deux
octets nous devons tenir compte de la longueur d’un élément du
vecteur.
Exemple:
Indice 1 2 3 4
Déplacement 0 1 2 3 4 5 67
|--------------------------------------------|
t |x x | x x | x x | xx |
---------------------------------------------
; AX t[i]
mov SI,i
ADD SI,SI; SI = SI * 2 (longeur d’un élément)
MOV AX, t[SI]
; t[i] AX
MOV SI, i
ADD SI, SI
MOV t[SI], AX
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
Implémentation em mémoire
Ligne 1 ligne 2 ligne 3
xx xx xx xx xx xx xx xx xx xx xx xx
0 1 2 3 4 5 6 7 8 9 10 11 12 13 15 16 17 18 19 20 21 22 23 24
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 caractère
AND AL, 11011111b ; force bit 5 à zero
MOV [BX], AL ; range le caractère
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
DF (registre flag) Incrémentation (DF=0) Décrémentation (DF=1) du pointeur utilisé pour les opérations
CLD DF=0 STD DF=1
CODE ENDS
END MAIN
TITLE PROG12.asm ; Balayer une chaîne de caractère et Remplacer une lettre particulière 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 données
;MOV ES,AX ; Initialiser le segment Extra
CLD ; DF=0 Auto-incrémentation 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 chaîne de caractères)
MOV AL, ‘G’ ; le caractère a scanner (balayer)
REPNE SCASB ; Répéter le balayage tant que les deux lettres ne sont pas égales ou jusqu’a C= 0.
JNE PASSE ; Saut si ZF=0 afficher le message 1 (égalité)
DEC DI ; Décrémenter DI (a la lettre G) car entre autre DI s’est automatiquement incrémenté
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
• entier factoriel(entier)
int factoriel(entier n)
{
si (n < 1) retourner 1
retourner n * factoriel(n-1)
}
Fin: pop AX; le résultat calculé par la fonction factoriel est dans AX
mov fact, AX
mov AX,4c00h
int 21h
Depiler:
POP AX
POP CX
mul CX
Push AX
CMP BX,CX
Ja depiler
ret
factoriel endp ; fin de la procédure
code ends
end debut ; fin du programme code