el oufir el mehdi

21
ECOLE NORMALE SUPÉRIEURE DE L'ENSEIGNEMENT TECHNIQUE - MOHAMMEDIA Compte Rendu TP - Assembleur i8086 (Sous EMU8086) Année Universitaire 2015/2016 Par : Enseignant : EL OUFIR EL MEHDI Professeur A.RAIHANI

Upload: el-oufir-el-mehdi

Post on 09-Jul-2016

242 views

Category:

Documents


10 download

TRANSCRIPT

Page 1: El Oufir El Mehdi

ECOLE NORMALE SUPÉRIEURE DE L'ENSEIGNEMENT TECHNIQUE - MOHAMMEDIA

Compte Rendu

TP - Assembleur i8086 (Sous EMU8086)

Année Universitaire 2015/2016

Par : Enseignant :

EL OUFIR EL MEHDI Professeur A.RAIHANI

Page 2: El Oufir El Mehdi

2

Sommaire :

Introduction générale ............................................................................................................................................. 3

Les registres du 8086 .............................................................................................................................. 3

Anatomie d’un programme en assembleur ............................................................................................ 4

Rapport sur les exercices : ..................................................................................................................................... 5

Programme 01 - La somme de deux nombres ........................................................................................ 5

Objectif ......................................................................................................................................................... 5

Méthode de résolution .............................................................................................................................. 5

Solution ........................................................................................................................................................ 5

Discussion et amélioration ........................................................................................................................ 5

– AVEC DIVISION ............................................................................................................................ 6

– AVEC MASQUAGE ....................................................................................................................... 7

Conclusion .................................................................................................................................................... 8

Programme 02 - La somme de deux vecteurs ........................................................................................ 9

Objectif ......................................................................................................................................................... 9

Solution ........................................................................................................................................................ 9

Discussion et amélioration ...................................................................................................................... 10

Conclusion .................................................................................................................................................. 12

Programme 03 – Les entries/Sorties – Manipulation des chaine de caractères .................................. 13

Objectif ....................................................................................................................................................... 13

Solution ...................................................................................................................................................... 13

Conclusion .................................................................................................................................................. 17

Programme 04 – L’heure et la date courante avec les procédures ...................................................... 18

Objectif ....................................................................................................................................................... 18

Méthode de résolution ............................................................................................................................ 18

Conclusion .................................................................................................................................................. 21

Page 3: El Oufir El Mehdi

3

Introduction générale :

Un langage d'assemblage ou langage assembleur est, en programmation informatique, un langage

de bas niveau qui représente le langage machine sous une forme lisible par un humain. Les combinaisons

de bits du langage machine sont représentées par des symboles dits « mnémoniques » (du grec

mnêmonikos, relatif à la mémoire), c'est-à-dire faciles à retenir. Le programme assembleur convertit ces

mnémoniques en langage machine en vue de créer par exemple un fichier objet ou un fichier exécutable.

Dans la pratique courante, le même terme assembleur est utilisé à la fois pour désigner le langage

d'assemblage et le programme assembleur qui le traduit. On parle ainsi de « programmation en

assembleur ».

Les registres du 8086 :

Le 8086 est un processeur 16 bits, c’est-à-dire qu’il traite des données codées sur 16 bits.

• AX registre d’usage général contenant des données. Les 8 bits de poids faible se nomment AL et les

8 bits de poids fort se nomment AH.

• BX registre d’usage général contenant des données. Comme ax, bx se d´décompose en BL et BH.

• CX registre d’usage général contenant des données. Comme AX, CX se décompose en CL et CH. DX

registre d’usage général contenant des données. Comme AX, dx se décompose en dl et DH.

• SI registre d’usage général contenant généralement le d´emplacement dans un segment d’une

donnée.

• DI registre d’usage général contenant généralement le d´emplacement dans un segment d’une

donnée.

• BP registre utilisé pour adresser des données dans la pile.

• SP registre pointeur de pile.

• IP registre pointeur d’instruction (compteur ordinal). Ce registre indique la prochaine instruction à

exécuter.

• Flags registre d’indicateurs de l’état du processeur. Certains bits de ce registre portent des noms.

Ce sont tous des indicateurs binaires :

– O le bit d’overflow est positionné par la plupart des instructions arithmétiques pour indiquer

s’il y a eut un débordement de capacité lors du calcul (un nombre trop grand ou trop petit)

– D bit de direction.

– S le bit de signe est positionné par la plupart des instructions arithmétiques pour indiquer le

signe du résultat (positif ou négatif – cf. section 1.4.2)

– Z le bit de zéro est positionné par la plupart des instructions arithmétiques pour indiquer

que le résultat du calcul est 0

– C le bit de carry (retenue) est positionné par la plupart des instructions arithmétiques pour

indiquer si le calcul a engendré une retenue qui devra être reportée sur les calculs suivants. – A le bit dit auxiliaire carry (retenue auxiliaire) est positionné par la plupart des instructions

arithmétiques pour indiquer une retenue entre bits de poids faible et bits de poids forts d’un

octet, d’un mot ou d’un double mot.

Page 4: El Oufir El Mehdi

4

– P le bit de parité est positionné par la plupart des instructions arithmétiques. Il indique si les

8 bits de poids faible du résultat comportent un nombre pair de 1.

• CS code segment segment contenant le programme en cours d’exécution.

• DS data segment segment contenant les données.

• ES registre segment auxiliaire pour adresser des données.

• SS stack segment segment contenant la pile.

Les valeurs des registres CS, DS et SS sont automatiquement initialisées par le système

d’exploitation au lancement du programme. Dès lors, ces segments sont implicites, c’est-à-dire que si l’on

désire accéder à une donnée en m´mémoire, il suffit de spécifier son offset sans avoir à se soucier du

segment.

Anatomie d’un programme en assembleur :

Un programme en assembleur a une forme bien particulière. Chaque ligne d’une source assembleur

comporte une instruction. Chaque ligne est composée de champs. De gauche à droite, on a :

– le champ étiquette, qui peut être vide.

– le champ mnémonique (le nom de l’instruction).

– le champ opérande (les arguments de l’instruction), qui peut être vide.

– le champ commentaire, qui peut être vide.

Une étiquette est un identificateur composé de lettres, chiffres et de caractères $, %, _ et ?

Quelques exemples d’étiquettes valides : boucle, fin_de_tant_que, ...

Une mnémonique est, généralement, composé uniquement de lettres. Quelques mnémoniques que

nous retrouverons souvent : MOV, CMP, LOOP, ... On pourra indifféremment écrire les mnémoniques

avec des lettres minuscules ou majuscules.

Les opérandes d’une instruction indiquent les données à traiter, soit sous la forme de valeurs

constantes, soit en spécifiant l’adresse mémoire (l’emplacement en mémoire) où se trouve la donnée,

soit le nom d’un registre contenant la donnée ou contenant l’adresse mémoire de la donnée.

Un commentaire commence par un caractère ; et se termine en fin de ligne.

Page 5: El Oufir El Mehdi

5

Rapport sur les exercices :

Programme 01 - La somme de deux nombres :

Objectif : Nous avons besoins d’un programme qui nous permettre d’additionner deux nombres (5+3).

Méthode de résolution : On va travailler directement avec le registre de 8 bits noté DL qui est spécialisé dans l’affichage. D’abord, on charge la valeur 5 dans DL par l'instruction MOVE, puis on additionne 3 au contenu de DL par l'instruction ADD.

Solution :

1. CODE SEGMENT 2. Main : 3. MOV DL,5 ; Charger DL avec 5 4. ADD DL,3 ; Additionner 3 au contenu de DL 5. 6. ADD DL,48 ; Pour obtenir le code ASCII de la contenu de DL 7. 8. MOV AH,2 ; Charger AH avec 2 (Paramètre de l’affichage) 9. INT 21H ; Appeler l’interruption 21H 10. 11. MOV AH,4CH ; Retour au DOS 12. INT 21H 13. 14. CODE ENDS 15. END Main

Discussion et amélioration : Cette solution est très limitée, parce qu’il aura un problème si la somme des deux nombres est supérieure à 9. Exemple de 9+3 :

Page 6: El Oufir El Mehdi

6

Comme vous le voyez on a affiché caractère par caractère avec l’addition de nombre 48 au nombre que l'on souhaite afficher, pour obtenir le code ASCII du caractère correspondant à ce nombre. Mais il y a que les nombre de 1 à 9 dans le table ASCII, pour cela on va faire deux solutions (valable juste pour un nombre ≤ 99) un avec la division et l’autre avec le masquage.

Dans ces solutions on va utiliser des directives d'assemblage pour définir des constantes, des variables, etc… au début du programme, exactement dans le data segment.

1. DATA SEGMENT 2. nb1 db 90 3. nb2 db 12 4. tmp db ? 5. diz db ? 6. unit db ? 7. DATA ends

AVEC DIVISION : On va diviser le nombre résultant par 10 par l’instruction DIV. Cette instruction fournit un quotient dans AL et un reste dans AH.

8. DATA SEGMENT ; Déclaration du « Data segment » 9. nb1 db 90 10. nb2 db 12 11. sum db ? 12. diz db ? 13. unit db ? 14. DATA ends 15. CODE SEGMENT 16. Main: 17. 18. MOV AX,DATA ; Définition 19. MOV ds,AX ; du « Data segment » 20. 21. XOR AX,AX ; Forcer les bits de AX à 0 22. 23. MOV AL,nb1 24. ADD AL,nb2 25. 26. MOV BL,10 27. DIV BL 28. 29. MOV diz,al 30. MOV unit,ah 31. 32. MOV DL,diz 33. ADD DL,48 34. MOV AH,2 35. INT 21H 36. 37. MOV DL,unit 38. ADD DL,48 39. MOV AH,2 40. INT 21H 41. 42. MOV AH,4CH 43. INT 21H 44. 45. CODE ENDS 46. END Main

Page 7: El Oufir El Mehdi

7

AVEC MASQUAGE : Cette méthode a besoin d’un ajustement décimal pour fonctionner. 1 - On va stocker la somme dans un variable temporelle parce qu’on va modifier le contenu. 2 - décaler le nombre résultant 4 fois à la droite par l’instruction SHR pour obtenir les dizaines. 3 – On va remettre le variable temporelle dans AL, Puis on va multiplier AL par 0F (00001111) grâce à l’instruction AND pour obtenir l’unité.

1. DATA SEGMENT 2. nb1 db 3 3. nb2 db 9 4. tmp db ? 5. diz db ? 6. unit db ? 7. DATA ends 8. CODE SEGMENT 9. Main : 10. 11. MOV AX,DATA 12. MOV ds,AX 13. 14. XOR AX,AX 15. 16. MOV AL,nb1 17. ADD AL,nb2 18. 19. DAA ; Ajustement décimale du résultat 20. 21. MOV tmp,AL 22. MOV CL,4 23. SHR AL,CL ; Décalage a droit 4 fois 24. MOV diz,AL 25. 26. MOV AL,tmp 27. AND AL,0Fh ; Forcer les 4 bits de poids fort à 0 28. mov unit,AL 29. 30. MOV DL,diz 31. ADD DL,48 32. MOV AH,2 33. INT 21H 34. 35. MOV DL,unit 36. ADD DL,48 37. MOV AH,2 38. INT 21H 39. 40. MOV AH,4CH 41. INT 21H 42. 43. CODE ENDS 44. END Main

Page 8: El Oufir El Mehdi

8

Conclusion : On a résolu le problème de l’affichage par deux méthodes le premier on forcer le AX à 0 et on diviser le contenue tout en l’affichant dans AX, dans la deuxième on utilise l’ajustement décimale du résultat, décalage à droite 4 fois est on force les 4bits de poids fort à 0.

Page 9: El Oufir El Mehdi

9

Programme 02 - La somme de deux vecteurs :

Objectif : Un programme qui fait la somme de deux vecteurs.

Méthode de résolution : Il est très courant de parcourir un tableau dans une boucle tout en voulant sortir de la boucle lorsqu'une condition est vérifiée ou si on arrive au dernier élément du tableau.

Donc la méthode c’est de parcourir les deux vecteurs au même temps élément par élément : - à chaque itération « i » on charge le vecteur v3[i] par le contenu de v1[i], puis on le additionne par le contenu de v2[i]. - afficher v3[i]. - il doit incrémenter les adresses des tableaux - il doit vérifier qu’on n’a pas encore atteint le dernier élément pour sortir la boucle.

Pour prendre les adresses qui pointent sur le premier élément de chaque table on va utiliser 3 registres avec l’utilisation de l’instruction LEA : BX v1 SI v2 DI v3

Et pour afficher les valeurs du tableau résultant on va faire la même chose qu’on a déjà fait dans l’exercice 1 avec la comparaison de l’élément v3[i] par 9 (J’ai utilisé la méthode de masquage dans ce exercice).

Solution :

1. DATA SEGMENT 2. v1 db 1,8,3,9,5,6 3. v2 db 9,8,4,0,1,8 4. v3 db 6 dup(?) 5. tmp db ? 6. diz db ? 7. unit db ? 8. nu db 6 9. DATA ENDS 10. CODE SEGMENT 11. Main: 12. 13. MOV AX,DATA 14. MOV DS,AX 15. 16. LEA BX, v1 ; Copier l’adresse de V1 dans BX 17. LEA SI, v2 18. LEA DI, v3 19. JMP Debut ; Saut vers l’étiquette « Debut » 20. 21. Boucle: MOV DL,44 22. MOV AH,2 23. INT 21H 24. 25. Debut: MOV AL,[BX] ; Charger AL par le contenu de l’@ dans BX 26. ADD AL,[SI] 27. MOV [DI],AL 28. 29. DAA ; Ajustement décimale du résultat

Page 10: El Oufir El Mehdi

10

30. 31. CMP AL,9 32. JA SiDeuxCh ; Saut vers « SiDeuxCh » si AL > 9 33. 34. MOV DL,AL 35. ADD DL,48 36. MOV AH,2 37. INT 21H 38. 39. JMP Continu ; Saut vers « Continu » 40. 41. 42. SiDeuxCh: XOR AH,AH 43. 44. MOV tmp,AL 45. MOV CL,4 46. SHR AL,CL 47. MOV diz,AL 48. 49. MOV AL,tmp 50. AND AL,0Fh 51. MOV unit,AL 52. 53. MOV DL,diz 54. ADD DL,48 55. MOV AH,2 56. INT 21H 57. 58. MOV DL,unit 59. ADD DL,48 60. MOV AH,2 61. INT 21H 62. 63. Continu: ADD BX ,1 ; Incrémenter BX par 1 64. ADD SI ,1 65. ADD DI ,1 66. DEC nu ; Décrémenter BX nu 67. JNZ Boucle ; Saut vers « Boucle » si n != 0 68. 69. MOV AH,4CH 70. INT 21H 71. 72. CODE ENDS 73. END Main

Discussion et amélioration : Supposant qu’on a 5 vecteurs, donc il doit utiliser 5 registres pour sauvegarder les adresses de chaque vecteur la chose qu’est impossible dans l’assembleur X86.

Pour résoudre ce problème on va manipuler seulement les indices des vecteurs par un seul registre (SI) comme dans la programmation en C.

Page 11: El Oufir El Mehdi

11

1. DATA SEGMENT 2. v1 db 1,8,3,9,5,6 3. v2 db 9,8,4,0,1,8 4. v3 db 6 dup(?) 5. tmp db ? 6. diz db ? 7. unit db ? 8. nu db 6 9. DATA ENDS 10. CODE SEGMENT 11. Main: 12. 13. MOV AX,DATA 14. MOV DS,AX 15. MOV SI,0 16. JMP Debut 17. 18. Boucle: MOV DL,44 19. MOV AH,2 20. INT 21H 21. 22. Debut: MOV AL,v1[SI] 23. ADD AL,v2[SI] 24. MOV v3[SI],AL 25. 26. DAA 27. CMP AL,9 28. JA SiDeuxCh 29. 30. MOV DL,AL 31. ADD DL,48 32. MOV AH,2 33. INT 21H 34. 35. JMP Continu 36. 37. SiDeuxCh: XOR AH,AH 38. MOV tmp,AL 39. MOV CL,4 40. SHR AL,CL 41. mov diz,AL 42. 43. MOV AL,tmp 44. AND AL,0Fh 45. mov unit,AL 46. 47. MOV DL,diz 48. ADD DL,48 49. MOV AH,2 50. INT 21H 51. 52. MOV DL,unit 53. ADD DL,48 54. MOV AH,2 55. INT 21H 56. 57. Continu: ADD SI ,1 58. DEC nu 59. JNZ Boucle 60.

Page 12: El Oufir El Mehdi

12

61. MOV AH,4CH 62. INT 21H 63. 64. CODE ENDS 65. END Main

Conclusion : D’après cette amélioration en déduire que l’utilisation des indices est plus efficace pour la manipulation des tableaux dans le langage assembleur, simple, lisible et facile dans la résolution.

Page 13: El Oufir El Mehdi

13

Programme 03 – Les entries/Sorties – Manipulation des chaine de caractères:

Objectif : L’objectif de cet exercice et de se familiariser avec les instructions de lecture et d’écriture des données en utilisant les interruptions.

1. Afficher un caractère ;

2. Afficher un caractère saisi au clavier par l'utilisateur ;

3. Afficher une chaîne de caractères ;

4. Afficher une chaîne de caractère saisie au clavier par l'utilisateur ;

5. Lire une chaîne de caractère et l'afficher en sens inverse.

6. Lire un caractère au clavier et tester si son code ASCII est celui d'un chiffre. Si c'est

le cas, ranger ce chiffre (et non son code ASCII) dans N1, sinon afficher "N".

7. Ecrire maintenant un programme (numread.asm) qui lit un nombre décimal au

clavier et le sauvegarde dans N1. La lecture s'arrête quand le caractère lu n'est pas

un chiffre (plus besoin d'afficher "N").

Solution :

1 - Afficher un caractère.

1. CODE SEGMENT 2. MAIN: 3. MOV DL,'A' 4. MOV AH, 2 5. INT 21H 6. 7. MOV AH, 4CH 8. INT 21H 9. CODE ENDS 10. END MAIN

Page 14: El Oufir El Mehdi

14

2 - Afficher un caractère saisi au clavier par l'utilisateur.

1. CODE SEGMENT 2. MAIN: 3. MOV AH, 1 ; Lecture du caractère 4. INT 21H ; Via l’interruption 21H 5. 6. MOV DL, AL ; 7. MOV AH, 2 ; Affichage du caractère 8. INT 21H ; Via l’interruption 21H 9. 10. MOV AH, 4CH 11. INT 21H 12. CODE ENDS 13. END MAIN

3 - Afficher une chaîne de caractères

1. DATA SEGMENT 2. CHAINE DB 'Bonjour','$' 3. DATA ENDS 4. CODE SEGMENT 5. MAIN: 6. MOV AX, DATA 7. MOV DS, AX 8. 9. MOV DX, OFFSET CHAINE ; 10. MOV AH, 09h ; Affichage de la chaine 11. INT 21H ; 12. 13. MOV AH, 4CH 14. INT 21H 15. CODE ENDS 16. END MAIN

Page 15: El Oufir El Mehdi

15

4 - Afficher une chaîne de caractère saisie au clavier par l'utilisateur

1. DATA SEGMENT 2. mot1 db 20 dup('$') 3. return db 13,10,'$' 4. DATA ENDS 5. CODE SEGMENT 6. MAIN: 7. MOV AX, DATA 8. MOV DS, AX 9. 10. MOV ah,0Ah ; 11. MOV dx,offset mot1 ; Lecture de la chaine 12. int 21h ; 13. 14. MOV ah,09h ; 15. MOV dx,offset return ; Saut de ligne et retour chariot 16. int 21h ; 17. 18. MOV ah,09h ; 19. MOV dx,offset mot1+2 ; Affichage de la chaine saisie 20. INT 21h ; 21. 22. MOV ah,4ch 23. INT 21H 24. code ends 25. END MAIN

5 - Lire une chaîne de caractère et l'afficher en sens inverse.

1. DATA SEGMENT 2. CHAINE DB 100 DUP ('$') 3. return db 13,10,'$' 4. DATA ENDS 5. CODE SEGMENT 6. MAIN: 7. MOV AX, DATA 8. MOV DS, AX 9. 10. MOV DX, OFFSET CHAINE 11. MOV AH, 10 12. INT 21H 13. 14. MOV ah,09h ; 15. MOV dx,offset return ; Affichage de retour chariot 16. int 21h ; 17. 18. XOR CX,CX 19. MOV CL,CHAINE[1] ; La longeur de la chaine dans CL

Page 16: El Oufir El Mehdi

16

20. boucle: 21. MOV SI,CX ; 22. ADD SI,1 ; 23. MOV DL,CHAINE[SI] ; Afficher carcatère par caractére 24. MOV AH, 2 ; en commencant par le dernier (Longeur-- + 1) 25. INT 21H ; 26. LOOP boucle ; 27. 28. MOV AH, 4CH 29. INT 21H 30. CODE ENDS 31. END MAIN

6 - Lire un caractère au clavier et tester si son code ASCII est celui d'un chiffre. Si c'est le cas, ranger ce chiffre (et non son code ASCII) dans N1, sinon afficher "N".

1. DATA SEGMENT 2. N1 DB ? 3. DATA ENDS 4. CODE SEGMENT 5. MAIN: 6. MOV AH, 1 ; Saisie du caractère 7. INT 21H 8. 9. CMP AL, "0" 10. JB nonchiffre ; Si le contenu de al<"0" : n'est pas un chiffre 11. 12. CMP AL,"9" 13. JA nonchiffre ; Si le contenu de al>"9" : n'est pas un chiffre 14. 15. SUB AL,"0" ; Sinon on fait la soustraction par "0" 16. MOV N1, AL ; pour avoir le chiffre 17. JMP FIN ; 18. 19. nonchiffre: MOV DL, "N" ; 20. MOV AH, 2 ; Afficher "N" 21. INT 21H ; 22. 23. Fin: MOV AH, 4CH 24. INT 21H 25. CODE ENDS 26. END MAIN

Page 17: El Oufir El Mehdi

17

7 - Ecrire un programme qui lit un nombre décimal au clavier et le sauvegarde dans N1. La lecture s'arrête quand le caractère lu n'est pas un chiffre.

1. DATA SEGMENT 2. N1 DB 0 3. DATA ENDS 4. CODE SEGMENT 5. MAIN: 6. MOV AX, DATA 7. MOV DI, AX 8. 9. MOV DI, OFFSET N1 10. WHILE: MOV AH, 1 11. INT 21H 12. 13. CMP AL, "0" ; Comparer AL avec ‘0’ 14. JB EXIT ; Quitter le programme si AL<‘0’ 15. 16. CMP AL,"9" 17. JA EXIT ; Quitter le programme si AL>‘9’ 18. 19. MOV N1, AL ; Charger N1 avec AL 20. JMP WHILE 21. 22. EXIT: MOV AH, 4CH 23. INT 21H 24. CODE ENDS 25. END MAIN

Conclusion : Nous avons identifié avec les instructions de lecture et d’écriture des chaines de caractères.

Page 18: El Oufir El Mehdi

18

Programme 04 – L’heure et la date courante avec les procédures :

Objectif : Dans cet exercice, on désire afficher la date et l’heure courante de notre PC. Pour ce faire, on fait appel à l’interruption 21H :

Lecture de l’heure : La fonction 2CH (chargée dans AH) de l’interruption 21H lit l’heure courante, telle qu’elle est stockée dans l’ordinateur. Au retour de l’appel, les registres contiennent les informations suivantes :

· CH : heures

· CL : minutes

· DH : secondes

· DL : centièmes de secondes

Lecture de la date : La fonction 2AH (chargée dans AH) de l’interruption 21H lit la date courante, telle qu’elle est stockée dans l’ordinateur. Au retour de l’appel, les registres contiennent les informations suivantes :

· AL : Le jour de la semaine codé (0 : dimanche, 1 : lundi, ...)

· CX : L’année

· DH : Le mois

· DL : Le jour

L’affichage de l’information :

· Une procédure aff_str pour afficher la chaine de caractères dont l’offset se trouve dans le registre AX, dans le segment courant.

· Une procédure aff_nb pour afficher la valeur du nombre dont le code en hexadécimal se trouvant dans les registres (CH, CL, DH, DL).

· Une procédure aff_jour

· Une procédure aff_mois

· Une procédure aff_annee

Méthode de résolution : Il suffit de lire l’heure courante ou la date via l’interruption 21H et d’afficher le contenu des registres d’une manière compréhensible pour un être humain sous la forme :

Bonjour

L’heure de votre PC est : 11h 20mn 45s 32c.

La date de votre PC est : Mardi 13 Février 2016

Et pour chaque registre qui contient l’information on fait la division par 10 pour l’afficher.

Page 19: El Oufir El Mehdi

19

1. pile segment para stack use16 2. db 256 dup (?) 3. pile ends 4. 5. DATA SEGMENT 6. MSG db "Bonjour !",10,13,"L'heure de votre PC est : ","$"; 7. MSG2 db 10,13,"La date de votre PC est : ","$"; 8. mois db "Janvier$$$","Fevrier$$$","Mars$$$$$$","Avril$$$$$", "Mai$$$$$$$","Jui$

$$$$$$","Juillet$$$","Aout$$$$$$", "Septembre$$","Octobre$$$","Novembre$$","Decembre$$"

9. semaine db "Dimanche$","Lundi$$$$","Mardi$$$$","Mercredi$", "Jeudi$$$$","Vendredi$","Samedi$$$$"

10. diz db ? 11. unit db ? 12. ch2 db "h ","$" 13. ch3 db "m ","$" 14. ch4 db "s ","$" 15. ch5 db "c.","$" 16. r1 db ? 17. espace db " $" 18. DATA ends 19. CODE SEGMENT 20. Main: 21. MOV AX,DATA 22. MOV ds,AX 23. 24. MOV DX,OFFSET MSG 25. CALL aff_str 26. 27. MOV AH,2CH ; Lecture de l’heure 28. INT 21H 29. 30. XOR AX,AX 31. 32. MOV AL,CH 33. CALL aff_nb ; Affichage des heures 34. 35. MOV DX,OFFSET ch2 36. CALL aff_str 37. 38. MOV AL,CL 39. CALL aff_nb ; Affichage des minutes 40. 41. MOV DX,OFFSET ch3 42. CALL aff_str 43. 44. MOV AL,DH ; Affichage des secondes 45. CALL aff_nb 46. 47. MOV DX,OFFSET ch4 48. CALL aff_str 49. 50. MOV AL,DL ; Affichage des centimes 51. CALL aff_nb 52. 53. MOV DX,OFFSET ch5 54. CALL aff_str 55. 56. MOV DX,OFFSET MSG2 57. CALL aff_str 58. 59. MOV AH,2AH ; Lecture de la date 60. INT 21H

Page 20: El Oufir El Mehdi

20

61. 62. call aff_jour ; Affichage du jour de la semaine 63. 64. MOV AL,DL ; Affichage du jour 65. CALL aff_nb 66. 67. call aff_mois ; Affichage du mois 68. 69. call aff_annee ; Affichage de l’année 70. 71. MOV AH,4CH 72. INT 21H 73. ; Procédure qui permet d’afficher l’année 74. aff_annee PROC near 75. PUSH DX 76. PUSH AX 77. PUSH CX 78. MOV AH,0 79. MOV AX,CX 80. MOV BL,100 81. DIV BL 82. MOV r1,AH 83. call aff_nb 84. MOV AL,r1 85. call aff_nb 86. POP CX 87. POP AX 88. POP DX 89. RET 90. aff_annee ENDP 91. 92. ; Procédure qui permet d’afficher le jour 93. aff_jour PROC near 94. PUSH DX 95. PUSH AX 96. PUSH CX 97. MOV AH,0 98. LEA BX,semaine 99. mov cl,9 100. mul cl 101. add bx,ax 102. mov cx,si 103. Lea DX,BX 104. call aff_str 105. MOV DX,OFFSET espace 106. CALL aff_str 107. POP CX 108. POP AX 109. POP dX 110. RET 111. aff_jour ENDP 112. 113. ; Procédure qui permet d’afficher le mois 114. aff_mois PROC near 115. PUSH DX 116. PUSH AX 117. PUSH CX 118. MOV DX,OFFSET espace 119. CALL aff_str 120. MOV AH,0 121. LEA BX,mois 122. mov al,dh 123. mov cl,10

Page 21: El Oufir El Mehdi

21

124. mul cl 125. add bx,ax 126. mov cx,si 127. Lea DX,BX 128. call aff_str 129. MOV DX,OFFSET espace 130. CALL aff_str 131. POP CX 132. POP AX 133. POP dX 134. RET 135. aff_mois ENDP 136. 137. ; Procédure qui permet d’afficher un nombre 138. aff_nb PROC NEAR 139. PUSH DX 140. PUSH AX 141. XOR AH,AH 142. MOV BL,10 143. DIV BL 144. 145. MOV diz,AL 146. MOV unit,AH 147. 148. MOV DL,diz 149. ADD DL,48 150. MOV AH,2 151. INT 21H 152. 153. MOV DL,unit 154. ADD DL,48 155. MOV AH,2 156. INT 21H 157. 158. POP AX 159. POP DX 160. RET 161. aff_nb ENDP 162. ; Procédure qui permet d’afficher une chaine 163. aff_str PROC NEAR 164. PUSH AX 165. MOV AH,9 166. INT 21H 167. POP AX 168. RET 169. aff_str ENDP 170. 171. CODE ENDS 172. END Main

Conclusion : Il Dans cet exercices on a décomposé notre problème en sous problèmes, chacun des sous problème est traité dans une procédure ce qui montre l’importance de cette notion au niveau de la programmation.