Best Prsenatationassembleur
Best Prsenatationassembleur
Best Prsenatationassembleur
Niveaux de programmation
Niveaux de programmation circuit logiques 0/1 --------------------------------------------------------------------------------unit de traitement micro-instructions
(UAL, chemins de donnes) = 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 mnmoniques
Djamal Rebane 2
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 BL, BL DL, 16 AX, DATA1 AX, 1 PROCHAIN BL DL ENCORE COMPTE, BL ; 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
MAIN
Djamal Rebane
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 6
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
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
Djamal Rebane 10
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 Arrt de programme:
Djamal Rebane
11
if then else
If ax =1 bx = 10; else { bx = 0; cx = 10; }
Assembleur
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
FAUX Condition ?
VRAI
Instructions m
Instructions j
Instructions k
Djamal Rebane
13
La boucle FOR
For (k=0; k<=10; k++) bx = bx + k; For:
Assembleur
MOV BX,0 MOV CX,0 CMP CX,10 JA Endfor ADD BX,CX INC CX JMP For
Endfor:
Djamal Rebane
14
WHILE
bx = 5 while (bx >0) bx = bx -1;
Assembleur
MOV BX,5 while: 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
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
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
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
Djamal Rebane
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 JE JC JB JNAE JS JO JPE JP JNZ JNE JNC JNB JAE JNS JNO JPO JNP
Saut si zro. Saut si gal. Saut si Retenue (infrieur). Saut si infrieur. Saut si ni suprieur ni gal. Saut si signe ngatif. Saut si dbordement. Saut si parit paire. Saut si parit. Saut si pas zro. Saut si diffrent. Saut si pas de retenue. Saut si pas infrieur. Saut si suprieur ou gal. Saut si aucun signe (positif). Saut si pas de dbordement. Saut si parit impaire. Saut si pas de parit.
Djamal Rebane
JNZ ZF = 1 JNE JNC JNB CF = 1 SF = 1 OF = 1 PF = 1 ZF = 0 JAE JNS JNO JPO JZ JE JC JB CF = 0 SF = 0 OF = 0 PF = 0 JNAE JS JO JPE 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
Djamal Rebane
32
Djamal Rebane
35
Djamal Rebane
36
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 DW MOV MOV CMP JNC ADD ADD DB 235FH BX, 7888H CX, 9FFFH BX, CX PASSE BX, 4000H CX, DATA1 ? AL, TEMP AL, 99 PROCHAIN BX ; 7888Hh BX
Compar e Oprand es Dest. > Src. Dest. = Src. Dest. < Src.
C F
ZF
0 0 1
0 1 0
; 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.
PASSE: TEMP
; TEMP AL ; TEMP = 99?. Avec (SUB AL, 99), la mme chose mais 0 ; Si ZF=1 (TEMP=99), Saute a PROCHAIN: ; Sinon incrmente BX ; Arrt du programme
AL
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 ; encore une fois si ce nest pas fini JNZ ENCORE 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 ? W val1 dw ? W val2 dd ? Si Bval se trouve ladresse offset 00404000 (hexa), loprateur offset renvoie les valeurs suivantes: MOV AX, offset bval ; AX = 00404000 MOV AX, offset W val1 ; AX = 00404001 MOV AX, offset W val2 ; 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
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
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 = A X * 2 ADD DI, 2 ; Chose est un tableau de W ords -> 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
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 Djamal Rebane 63 END MAIN
L a b . . y z
Hex
41 42
61 62
79 7A
01111001 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
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
Djamal Rebane
69
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
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 Octet/Octet Mot/Mot Mot/Octet DoubleMot/Mot NUM. (> ou <) AL = Octet CBW AX = Mot CWD AX = Mot DXAX = DoubleMot DENOM. (> ou <) Reg. ou mem. Reg. ou mem. Reg. ou mem. Reg. ou mem. AL AX AL (Erreur si 128>AL>+127) AX (Erreur si 32768>AX>+32767) QUOTIENT RESTE AH DX AH DX
RESULTAT AX (CF=OF=1 si AH possde une partie du rsultat, m ais 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) DXAX(CF=OF=1 si DX possde une partie du rsultat, m ais 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) DXAX (mme rem arque que prcdemment)
Mot/Mot
AX
Reg. ou mem.
Mot/Octet DoubleMot/Mot
AL = Octet CBW
Reg. ou mem.
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: 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+AX BX ; 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
ARRIERE:
MAIN
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
;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
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 1 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
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
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
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
; 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
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
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
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
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
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
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 | ---------------------------------------------
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
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
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 Dep. Ch. Oct. Dep. Ch. Mot Sav. Ch. Oct. Sav. Ch. Mot Chg. Ch. Oct. Chg. Ch. Mot Cmp. Ch. Oct. Cmp. Ch. Mot Scn. Ch. Oct. Scn. Ch. Oct. Mnmonique MOVSB MOVSW STOSB STOSW LODSB LODSW CMPSB CMPSW SCASB SCASW Destination ES:DI ES:DI ES:SI ES:SI AL AX ES:DI ES:DI ES:DI ES:DI Source DS:SI DS:SI AL AX DS:SI DS:SI DS:SI DS:SI AL AX Prfixe REP REP REP REP / / REPE/REPNE REPE/REPNE REPE/REPNE REPE/REPNE
DF (registre flag) Incrmentation (DF=0) Dcrmentation (DF=1) du pointeur utilis pour les oprations 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 CX 0) ; 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 CX 0 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 ; Charger le compteur avec 9 (la taille de la chane de caractres) MOV CX, 9 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
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
Djamal Rebane
152
Djamal Rebane
153
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