Title: Assembleur
1Assembleur
2Niveaux 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
3Structure dun programme assembleur 8086
- TITLE nom donner un nom au programme
- PILE SEGMENT STACK déclaration dun segment
de pile -
dont le nom est pile - ..........
- ..........
- PILE ENDS fin de la déclaration de la pile
- DONNEE SEGMENT déclaration dun 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
dindication du point dentrée du code - .................................
- LECODE ENDS fin de la déclaration du
code - END Debut fin du point
dentrée du code
4Exemple
- 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 CSCODE, DSDATA
- 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)
5Pourquoi les segments?
- À l'origine
- - Pour pouvoir adresser plus de 64 Ko de
mémoire dans un - programme car les registres sont sur16
bits - En pratique aujourd'hui
- - Permet de séparer clairement des zones
mémoires selon - leur rôle
- Exemple la pile ne peut pas être écrasée par
des données ou déborder sur des données / code - Mais cela est contraignant ...
6Suite
- 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 AB
- - Adresse réelle A 16 B
- Exemple (les nombres sont en hexa)
- 310027EE correspond à l'adresse 31000 27EE
337EE - Décaler de 4 bits en binaire revient à décaler
d'un chiffre en hexa
7Suite 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 segmentoffset
- Exemples
- - CSIP adresse de la prochaine
instruction à exécuter - - DSSI adresse d'une donnée
- - SSSP adresse du haut de la pile
8- Vos programme sources, écrits en assembleur,
doivent avoir lextension - .asm pour ASseMbler
9Dé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ésdatas5 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 bytesDQ 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
10Les entrées Sorties en assembleur
- Pour réaliser les opérations standards
(affichage, saisie), le système dexploitation
(ici DOS) fournit les fonctions pré-écrites
suivantes - Affichage dun caratère mov DL, A
caractère A est transfére dans DL -
mov AH, 2 fonction no. 2 -
int 21h appel au DOS -
- Affichage dune chaine de caractères
- mov DX, offset chaine
pointe vers ladresse du premier -
caractère de la chaîne de caractères chaine - mov AH, 09h fonction no. 9
- int 21h
- Saisie dun caratère mov AH, 1 fonction
no. 1 - (avec écho) int 21h
résultat est mis dans AL
11- Saisie dun caractère mov AH, 7 fonction
no. 7 - (sans écho) int 21h
résultat dans AL - Arrêt de programme mov AX, 4C00h
-
int 21h - À mettre à la fin de chaque fin programme cest
léquivalent du - return (0) en C. Ces instructions ont pour effet
de retourner au DOS
12Léquivalent de quelques instructions du langage
C en assembleur
- if then else Assembleur
- If ax 1
if CMP AX, 1 - bx 10
JNZ Else - else
- bx 0
Then MOV BX,10 - cx 10
JMP endif -
Else MOV BX,0 -
MOV CX,10 -
endif ..............
13 Instruction i Si condition alors Instructions
j Sinon Instruction m Fin si Instructions k
14- La boucle FOR Assembleur
- For (k0 klt10 k)
MOV BX,0 - bx bx k
MOV CX,0 -
For CMP CX,10 -
JA Endfor -
ADD BX,CX -
INC CX -
JMP For -
Endfor
15- WHILE Assembleur
- bx 5
MOV BX,5 - while (bx gt0)
while CMP BX,0 - bx bx -1
JLE Endwhile -
DEC BX -
JMP while -
Endwhile
16- 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 ...........
17- Écrire le code de linstruction En
assembleur - if (agtb) (c lt d)
if cmp a, b
jng endif
................ -
cmp c, d -
jnle endif -
.............. -
endif - Exercice coder en assembleur les instructions
suivantes - 1. if (a gtb) (c gt d)) 2.
for (i1 i lt 10 i) -
-
-
18Liste des registres les plus utilisés
- A. Registres généraux
- AX (A pour accumulateur) joue le rôle dopé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 dextension. - 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 datteindre nimporte quel
élément de la pile (exemple - MOV AX,BP2).
- SP (Stack pointer) pointe sur le sommet de la
pile son contenu est automatiquement changé par
les instructions PUSH et POP.
19- B. Registres spéciaux
- IP (Instruction pointeur) contient ladresse de
linstruction qui suit celle qui est en cours
dexé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 lintermédiaire de AX, comme
pour DS. - SS (Stack Segment) segment contenant la pile.
- C. Registre indicateur utilisé pour sauvegarder
des états particuliers du microprocesseur en
référence à la dernière instruction exécutée.
Quelques bits seulement de ce registre ont une
signification sont nommés CF (retenue), OF
(débordement), etc.
20(No Transcript)
21Format standard dune instruction
Label Mnémonique Opérandes commentaire Label
est un identificateur permettant de désigner un
endroit dans le code source, soit une
instruction, soit une donnée. Si le label est
placé avant une instruction, on fait référence à
ladresse de cette instruction. Si cest avant
une donnée, on fait référence à ladresse de
cette instruction. Le label de code doit se
terminer par deux points (). Il sert général
comme destinations des instructions ou des retour
de début des boucles de répétition. Le label de
donnée ne contient pas les deux points() à la
fin. Il sert dans ce cas là comme
identificateur.
22- 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 dun registre, un opérande mémoire, une
expression constante ou le nom dun 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
linstruction correspondante.
23Quelques instructions de base-1
- Affectations
- Registres lt-- 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 lt-- Adresses Mémoire
- Mov AX, Offset variable AX lt- adresse de
variable - Mov CX, 5Ah CX lt- valeur à l'adresse 5A en
hexa
24Quelques instructions de base- 2
- Arithmétique
- Incrémentation
- INC AX AX lt- AX 1
- Inc ma_variable
- Décrémentation
- DEC AX
- Dec ma_variable
- Addition
- ADD AX, 5 AX lt- AX 5
- ADD BH, toto BH lt- BH toto
- Add toto, Cx toto lt- toto Cx
- Soustraction
- SUB AX, 5 AX lt- AX 5
- SUB BH, toto BH lt- BH toto
- SUB toto, CX toto lt- toto - CX
25Quelques instructions de base-3
- Logique
- AND bit à bit
- MOV AH, 0101b AH lt- 5
- MOV BH, 1001b BH lt- 9
- AND AH, BH AH lt- AH AND BH AH vaut 0001b, soit
1 - OR bit à bit
- MOV AH, 0101b AH lt- 5
- MOV BH, 1001b BH lt- 9
- Or AH, BH AH lt- AH OR BH AH vaut 1101b, soit
13 (841) - XOR bit à bit
- MOV AH, 0101b AH lt- 5
- MOV BH, 1001b BH lt- 9
- XOR Ah, BH AH lt- AH XOR BH AH vaut 1100b,
soit 12 (84) - NOT bit à bit
- MOV AH, 0101b AH lt- 5 Not AH AH lt- NOT AH
AH vaut 1010b, soit 10 (82)
26Quelques 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
27- 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 résultat. 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 prés de
127octets). Il faut donc prendre garde que ce
label puisse être atteint.
28(No Transcript)
29JZ Saut si zéro. ZF 1 JNZ
JE Saut si égal. ZF 1 JNE
JC Saut si Retenue (inférieur). CF 1 JNC
JB Saut si inférieur. CF 1 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. PF 1 JPO
JP Saut si parité. PF 1 JPO
JNZ Saut si pas zéro. ZF 0 JZ
JNE Saut si différent. ZF 0 JE
JNC Saut si pas de retenue. CF 0 JC
JNB Saut si pas inférieur. CF 0 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. PF 0 JPE
JNP Saut si pas de parité. PF 0 JP
30Modes dadressage
- 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.
31Modes dadressage
- Mode immédiat
- Lopérande est codée avec linstruction
- mov AX, 568
- Mode registre
- Lopérande est un registre de donnée ou dadresse
- mov AX,BX
- Mode mémoire direct
- Lopérande est désigné par ladresse donnée dans
linstruction - mov 0hC040,AL
- mov DS 0hC040,AL
- mov CSvar2,AX
- mais pas
- mov 0hFE15 var2,AX
32Modes dadressage pour accéder aux données
- Mode mémoire indirect
- Lopérande est désignée par une adresse placée
dans les registres dadresses donnée dans
linstruction - mov AX,SI BX,BP,SI,DI peuvent servir de
registre - pointeur
- 1. Indirect avec déplacement
- Ladresse contenu du registre dadresse
déplacement (le registre dadresse nest pas
modifié) - mov AX, DI
- mov BX,DI6
33Modes dadressage pour accéder aux données
- 2. Indirect avec index
- Ladresse contenu du registre dadresse
contenu du registre dindex (le registre
dadresse nest pas modifié) - mov BPDI,AX
- les couples possibles sont BP-DI,
- BP-SI, BX-DI, BX-SI
34Quelques notes utiles
- La déclaration dune chaîne de caractères est
mise en - '' '' ou ' ' .
- Le caractère '' indique la fin dune 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. - Lassembleur 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 à lintérieur du segment de
code MOV AX, nom_du_segment_de_donnees
MOV DS, AX
35Un petit mot sur linstruction 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)
- NOTE Pas de transfert de mémoire à mémoire
-
36Applications de quelques instructions sur des
exemples
37Compare Opérandes CF ZF
Dest. gt Src. 0 0
Dest. Src. 0 1
Dest. lt Src. 1 0
Instruction CMP (Comparer) CMP destination,
source Linstruction CMP affecte les
indicateurs AF, OF, SF, PF, CF et ZF mais seuls
CF et ZF sont utilisés. Lopérande destination
peut être dans un registre ou dans une mémoire.
Lopérande source peut être dans un registre,
dans une mémoire, ou en mode immédiat. Les
opérandes (destination et source) ne changent
pas. DATA1 DW 235FH MOV BX, 7888H
7888Hh ? BX MOV CX, 9FFFH CMP
BX, CX BX lt CX ? CF1 ? 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 (lt ou gt). 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 ZF1
(TEMP99), Saute a PROCHAIN INC BX
Sinon incrémente BX PROCHAIN HLT
Arrêt du programme
38- TITLE prog1.asm Exemple sur CMP, Trouver
loctet 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 CSCODE, DSdata génération de
ladresse du segment de code et de données - MOV AX, DATA
Initialiser le registre DS pour récupérer
ladresse 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
39- TITLE prog2.asm Exemple sur ROL, Trouver le
nombre de 1 dans un mot - Pile segment stack déclaration dun 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 CSCODE, DSDATA
- 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)
40Quelques explications
- Litération On peut également transcrire une
boucle à laide de linstruction LOOP
nécessitant 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
exécuté tant que la valeur de CX nest pas
nulle. A chaque itération, CX est décrémenté
dune 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
41for (cx5 cxgt0 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 dune unité CX.
si CX gt 0 fait le saut à for
42- On peut aussi utiliser LOOPE/LOOPZ/LOOPNE/LOOPNZ
pour signifier - a.LOOPE ( Loop while Equal ) Monlabel
- Décrémente CX, puis, si CX ltgt 0 et ZF 1,
fait un saut à MonLabel. - Mnémonique équivalent LOOPZ
- b. LOOPNE ( Loop while not Equal ) Monlabel
- Décrémente CX, puis, si CX ltgt 0 et ZF 0,
fait un saut à - MonLabel.
43 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 ????
44- 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.
45- Manipulation de données
- Operateur offset renvoie ladresse à laquelle
est située un label de donnée - Exemple
- Bval db ?
- Wval1 dw ?
- Wval2 dd ?
-
- Si Bval se trouve à ladresse offset 00404000
(hexa), lopérateur 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 déclarée au départ pour un opérande. Par
exemple, -
- double dd 12345678h
-
- MOV AX, double erreur
- Mais si on insère la directive WORD PTR, on peut
copier le mot de poids faible (5678h) - dans AX cest-à-dire
46Un mot sur les macros Étant donné que
certaines instructions se répètent constamment
dans un programme, lécriture 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 représente. Lorsque lassembleur
rencontrera ce nom dans votre code source, il le
remplacera par les lignes de code quil désigne.
Ces lignes forment une macro .
47- Les macros, à la différence des procédures, 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-même 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
différence avec les fonctions qui ne sont écrites
quune seule fois mais peuvent être appelées
aussi souvent quon veut à laide dun CALL
(quon verra plus tard dans ce cours).
48- Voici comment écrire une macro
- lexemple suivant sert à écrire un message à
lécran.
49affiche 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
50- Lassembleur 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 lon veuille écrire à
lécran 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 léquivalent de endln en C-C
51Présentation dautres exemples
52- TITLE ex3_somme somme de deux nombres
- PILE SEGMENT STACK déclaration de pile.
- Pour
cet exemple, la pile nest 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 ladresse de début de chaine - MOV AH, 09h
fonction qui affiche une chaîne de caractères
- INT 21h
- ENDM fin de la macro
- DATA SEGMENT déclaration de variables
- val1 db 0
- val2 db 0
- recup_val1 db 10,13,'veuillez taper la
valeur1',10,13,'' 10 et 13endl du C - recup_val2 db 10,13,'veuillez taper la
valeur2',10,13,' - aff_resu db 10,13,'la valeur saisie
est',32,'' caractère de fin de chaine - DATA ENDS
53- SCODE SEGMENT zone de code
- ASSUME CSSCODE, DSDATA génération de
ladresse du segment de code et de données - DEBUT entrée du code
- MOV AX, DATA Initialiser le registre DS
pour récupérer ladresse du - MOV DS, AX segment de donnée
-
- à 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
grâce à la fonction 1 le caractère 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
-
54- 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 nest 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 gt0 pour dire - INT 21h que lexécution
sest déroulée correctement. - Équivalent
en c de return 0 - SCODE ENDS fin du segment de code
- END DEBUT
55- TITLE ex4_max détermine et affiche le maximum
de deux nombres - introduits à travers
le clavier - PILE SEGMENT STACK
- DW 100 DUP (?) déclaration dune
pile de 100 éléments - PILE ENDS
- affiche macro chaine à la compilation,
lassembleur recopie lensemble - 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 -
ladres 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 13endl 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
56- SCODE SEGMENT
- ASSUME CSSCODE, DSDATA génération
d,adresses pour les segments de code et de
données - DEBUT entrée du code
- Initialiser le registre DS par ladresse du
segment de donnée générée 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 caractère - 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
-
57- 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 lentrée du
code
58- Exemple 5 que fait cette portion de code?
- MOV BX, offset Alphabet alphabet
étant une chaîne de caractères - MOV CL, 26
- MOV BX, CL 26
caractères - MOV AL, 65h 65 'A' dans AL
- MaBoucle INC BX
- MOV BX, AL
écrit dans le tableau - INC AL
AL caractère 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, alphabetbx
- MOV AH,2
- INT 21h
- MOV DL, permet
dafficher un blanc
59- Exemple 6 que fait la portion de code
ci-dessous ? - MOV BX, offset Chose Met ladresse de
début du tableau chose dans BX - MOV DI, 0 Index
nul - MOV AX, 1
- MOV CX, 11 11
éléments dans le tableau - MaBoucle MOV BXDI, AX écrit dans le tableau
- SHL AX, 1 AX AX
2 - ADD DI, 2 Chose
est un tableau de Words -gt 2 octets - DEC CX
- JNZ MaBoucle
- Remarque 1 Lors de la saisie dune chaîne de
caractères au clavier, les deux premiers termes
sont réservés le premier étant la dimension et
le deuxième est le nombre effectif de caractères. - Remarque 2 Les registres SI, DI, BX peuvent
être utilisés pour les indices de tableaux
indifféremment.
60- TITLE sommedetroixnombres ce programme fait
la somme des trois
premiers nombres entiers i.e 123 - 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
61- SCODE SEGMENT
- ASSUME CSSCODE, DSDATA
- 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
62- Exemple 7 Exemple sur ROL, Trouver le nombre de
0 dans un double-mot -
63- 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 CSSCODE, DSDATA 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
CF1 - INC CL Si CF 0,
incrémenter le compteur du nombre de 0
64Conversion Minuscule en Majuscule
L Hex Binaire
A 41 01000001
B 42 01000010
.
.
Y 59 01011001
Z 5A 01011010
L Hex Binaire
a 61 01100001
b 62 01100010
.
.
y 79 01111001
z 7A 01111010
65- 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 CSSCODE, DSDATA
- 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 tSI prochain
caractère - CMP AL, 61H Si lt a (61H est le code ASCII
de a) - JB PASSE donc pas besoin de convertir
- CMP AL, 7AH Si gt z (7AH est le code ASCII
de z)
66- Exemple 9 lit une chaîne de caractères et
laffiche à lenvers - Programme palin
67- 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 csscode, dsdata
- 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 chaîne de caractères - qui se termine dès
quon tape le retour chariot (touche entrée) - int 21h
68- 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 ptrsi
- 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 ptrsi
- mov AH,02h
- int 21h
- dec SI
- jmp fs
69Une autre manière de le faire
- debut
- xor dx,dx
- mov DL,si1 récupération du nombre
de caractères lus - la taille à récupérer est obtenue par
lobjet de destination - car si1 na 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,reponsesi
- mov ah,02h
- int 21h
- dec si
- jmp f_s
70Une troisième manière de le faire
- debut
- xor DX,DX
- mov DX,reponsesi récuperation du
nombre de caractères lus - la taille à récupérer est obtenue par
lobjet 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,reponsesi
- mov AH,02h
- int 21h
- dec SI
- jmp fs
- fins
- mov AX,4c00h
71- MULTIPLICATION ET DIVISION SIGNÉE (IMUL /
IDIV) reg. (ou mém.) - 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 signées.
- MULTIPLICATION ET DIVISION SIGNÉE (IMUL /
IDIV) reg. (ou mém.) - 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 signées.
DIVISION SIGNEE NUM. (gt ou lt) DENOM. (gt ou lt) QUOTIENT RESTE
Octet/Octet AL Octet CBW Reg. ou mem. AL AH
Mot/Mot AX Mot CWD Reg. ou mem. AX DX
Mot/Octet AX Mot Reg. ou mem. AL (Erreur si 128gtALgt127) AH
DoubleMot/Mot DXAX DoubleMot Reg. ou mem. AX (Erreur si 32768gtAXgt32767) DX
MULTIPLICATION SIGNEE OPERANDE 1 (gt ou lt) OPERANDE 2 (gt ou lt) RESULTAT
Octet/Octet AL Reg. ou mem. AX (CFOF1 si AH possède une partie du résultat, mais si celui-ci nest pas large ? pas besoin de AH, le bit de signe est copié aux bits non utilisés de AH et la CPU force CFOF0 pour lindiquer)
Mot/Mot AX Reg. ou mem. DXAX(CFOF1 si DX possède une partie du résultat, mais si celui-ci nest pas large ? pas besoin de DX, le bit de signe est copié aux bits non utilisés de DX et la CPU force CFOF0 pour lindiquer)
Mot/Octet AL Octet CBW Reg. ou mem. DXAX (même remarque que précédemment)
DoubleMot/Mot
72- 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 CSCODE, DSDATA
- 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
73Expression arithmétiqueX (A2 BC)/(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 DXAX
A2 MOV BX,DX MOV CX,AX BXAX A
2 MOV AX,B IMUL C DXAX BC
ADD AX,CX AX AX CX ! faites attention,
il peut y avoir une retenue ici ADC DX,BX
DXAX A2BC la retenue sil
y a lieu avec ADC MOV CX, D SUB CX,3
cx D -3 IDIV CX
AX (A2
BC)/(D-3) MOV X,AX
X ax (A2 BC)/(D-3) stocker le résultat
RET Arithmetique endp fin de
la procedure ............
74Conversion dune 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 lassembleur comme la chaîne de caractères
827. Pour avoir sa valeur numérique, il y a
lieu de la convertir suivant lalgorithme
suivant
75Algorithme de conversion
- nbre nombre de caractère lus
- Nombre 0
- Repeter
- chiffre caractère lu
- nombre nombre 10chiffre
- nbre nbre -1
- Si nbre gt 0 aller à repeter
-
76Exemple
- 827
- nombre 0
- Chiffre 8
- nombre nombre 10 chiffre 0108 8
- Chiffre 2
- nombre nombre 10 2 810 2 82
- Chiffre 7
- Nombre nombre 10 7 82107 827
-
77En 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 CSSCODE,DSSDATA
- 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,chainesi
78- 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 DSDX (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 -
- 1 nombre de
caractères lus (sans compter le retour chariot). - cette valeur est
installée par la fonction. - 2 À partir de cette
position, on trouve les caractères lus
79Conversion dune valeur décimale en une chaîne de
caractères
- Toute information affichée sur écran est
considérée comme un caractère. 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 récupérer les chiffres 8, 2 et 7 par une
succesion de divisions par dix (ces chiffres
seront récupérés 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, récupérant les chiffres dans
lordre inverse, peut être comme suit
80Algorithme
- k 0
- do
- quotient nombre / 10
- reste nombre 10
- tabk reste
- nombre quotient
- k
- while (quotient ! 0)
-
81Dans 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 déclarer result
dans le segment de données - mov dx,offset enter retour chariot 10,
13 dans le segment de données - mov ah,09h
- int 21h
- mov ax,result
- mov SI, offset tabconv tabconv est à
déclarer dans le segment de données - mov start, offset tabconv
- start
sert à garder le début 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 ptrsi,AH
- mov AH,0
- inc SI
82- fin_div
- add AH,48
- mov byte ptrsi,AH
- tabconv contient le nombre converti à
lenvers - 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 ptrsi
- mov byte ptrbx , AH
- dec si
- inc bx
- jmp st_bcl
83- fin_bcl
- mov byte ptrbx,10
- inc BX
- mov byte ptrbx,13
- inc BX
- mov byte ptrbx,''
- mov dx,offset tabsortie
- mov ah,09h
- int 21h
- MOV AX,4C00H
- INT 21H
- SCODE ENDS
- END DEBUT
84 La directive EQU La directive EQU a un rôle
voisin de celui des macros. Elle permet de
remplacer un simple mot par dautres plus
complexes. Son intérêt est quelle peut être
invoquée en plein milieu dune ligne.
85Quelques 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
86Les piles
87- 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!). - Les instructions PUSH et POP
- Les instructions PUSH et POP sont les
instructions qui servent à empiler et dépiler les
données. - - PUSH registre met le contenu du registre dans
la pile (empilement) - - POP registre récupère le contenu de la pile et
le stocke dans le registre (dépilage
88- Ainsi, l'instruction
- PUSH BX
- empile le contenu du registre BX,
- et l'instruction
- POP AX
- récupère le contenu du sommet de la pile et le
transfère dans AX.
89- 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...
90- PUSH AX
- PUSH BX
- MOV AX, 0140
- ADD BX, AX
- MOV 0140, BX
- POP BX
- POP AX
91- Les registres SS et SP Les registres SS et SP
sont deux registres servant à gérer 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 début du programme
- SP (Stack Pointer, littéralement pointeur de
pile) est le déplacement pour atteindre le sommet
de la pile (16 bits de poids faible).
92- 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.
93- PUSH SP lt- SP - 2
- POP SP lt- SP 2
- Ainsi, lorsque la pile est vide SP pointe sous la
pile (la case mémoire en-dessous de la base de la
pile) car il n'y a pas de case occupée. Un POP
provoquera alors une erreur...
94- Déclarer une pile
- Pour pouvoir utiliser une pile, il faut la
déclarer, c'est-à-dire réserver un espace mémoire
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 définir une pile, il s'agit tout
d'abord de la déclarer grâce à la directive
SEGMENT stack.
95- 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 - segment_pile SEGMENT stack mot clef stack pour
pile - DW 100 dup (?) réserve espace
- base_pile EQU this word etiquette base de la
pile - segment_pile ENDS
- 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). -
96 97- Suite aux déclarations, il faut écrire une
séquence d'initialisations - ASSUME SSsegment_pile génère 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!
98Les 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...).
99(No Transcript)
100- La déclaration d'une procédure
- Etant donnée qu'une procédure est une suite