Вы находитесь на странице: 1из 6

Petits exercices pour apprendre les bases

Dernire modification le 12/06/03 NB : Ces exercices ne sont que de petits exemples pour apprendre le langage. Ils sont trs simples et ils sont classs en fonction de leur forme et non de leur thme ou de leur difficult. 1) Arithmtique signe/non signe En arithmtique signe sur 16 bits, comment s'crivent les nombres 199 et 32768 (donner le rsultat en complment 2 et en notation hexa) ? En arithmtique non signe sur 16 bits, comment s'crivent les nombres 32768 et 65536 (donner le rsultat en notation hexa) ? 2) Procdures et macros Ecrire une procdure qui parmi deux entiers (passs en paramtres sur la pile) renvoie le plus grand dans AX. Ecrire une procdure qui premier. dit si un nombre positif (pass dans AX) est

Ecrire une macro qui crit un entier l'cran. Ecrire une macro qui fait revenir le curseur de lcran la ligne Ecrire une macro qui lit une chane de caractres au clavier. 3) Programmes COM Ecrire un programme COM qui affiche les noms des fichiers et dossiers du rpertoire courant. Ecrire un programme COM qui crit l'cran les 20 premiers nombres premiers. 4) Programmes EXE Ecrire un programme EXE qui calcule la somme des n premiers entiers (n tant une constante dfinie dans le programme avec DEF) et qui l'crit l'cran. Faire une boucle (cest--dire ne pas utiliser la formule de Pascal) !

Correction

NB : - Pour chaque exercice, il existe de trs nombreuses faons de sy prendre. Nous nen proposerons quune, sans nous soucier doptimisation ni de propret professionnelle du code... Le seul but est que vous puissiez voir si vous avez compris la logique du langage assembleur. - Pour lire la correction, mettez la taille 10 ! 1) Arithmtique signe/non signe En arithmtique signe sur 16 bits, comment s'crivent les nombres 199 et -32768 (donner le rsultat en complment 2 et en notation hexa) ?
Le nombre 199 scrit 16*12 + 7 ce qui donne en hexa C7 = 00C7 Le nombre -32768 est loppos de +32768 qui scrit : 8*16^3, soit 8000 en hexa. Inversons les bits : 0 va devenir F et 8 va se transformer en 7 (car 8h = 1000b et 0111b = 7h). Ca donne donc 7FFF. Ajoutons une unit : a fait 8000.

Petite question 8000 balles : -32768 scrit donc 8000 en hexa, tout comme le nombre 32768 !! O est donc le problme ? ? ? Rponse 32768 balles : on travaille ici sur 16 bits donc tous les nombres ne sont pas reprsentables ! On peut seulement coder les entiers allant de 32768 +32767. Si on cherche dpasser ces limites du ct positif, on va se retrouver avec un nombre ngatif (et vice versa) ! Ici, 8000h code bien le nombre 32768 mais le nombre +32768 nest pas reprsentable sur 16 bits.

En arithmtique non signe sur 16 bits, comment s'crivent les nombres 32768 et 65536 (donner le rsultat en notation hexa) ?
Le nombre 32768 scrit 8000 (voir la question prcdente). Remarque : ici nous sommes toujours sur 16 bits, mais en arithmtique non signe. Les nombres reprsentables sont compris entre 0 et 65535. Le nombre 65536 nest pas reprsentable sur 16 bits (car 65536 = 16^4 scrit en hexa : 10000 ce qui demande au moins 17 bits) !

2) Procdures et macros Procedure qui parmi deux entiers (passs en paramtres sur la pile) renvoie le plus grand dans AX
comment * Procdure qui renvoie le maximum de deux entiers SIGNES Paramtres : sur la pile Rsultat : AX = maximum des deux nombres * max proc .386 pushf push near bxbp ;sauvegarde des flags ;sauvegarder BX et BP

mov bp,sp ;pour lire les paramtres mov ax, word ptrss:[bp + 8] ;lisons le deuxime paramtre mov bx, word ptrss:[bp + 10] ;et le premier cmp ax, bx ;comparaison (soustraction) jge MAXfini ;ax est-il plus grand (sign) ;NB : utilisez jae si vous voulez comparer des nombres non signs mov ax, bx ;bx est le plus grand MAXfini: pop popf ret endp bpbx 4 ;restauration de BP et BX ;restauration des flags ;dpiler paramtres et retour

max

Procdure qui dit si un nombre positif (pass dans AX) est premier
comment * Procdure qui dit si un nombre positif est premier Paramtres : AX = nombre tester Rsultat : AX = 1 si le nombre est premier et 0 sinon

* test_prem proc

near .386 pushf pusha push cmp jb je push pop mov mov

ds ax, 2 TPnon_premier TPpremier

;sauvegarde des flags ;sauvegarde des reg. gnraux ;sauvegarde de DS ;le nombre est-il < 2 ? ;oui ? alors pas premier ! ;si = 2 alors premier !

cs ;mettrecs ds ; dans ds word ptrds:[TPsto_nombre], ax;stocker le nombre tester bx, 2 ;on va le diviser par 2 dx, dx bx dx, 0 TPnon_premier ax, TPsto_nombre bx bx, ax TPpremier TPprochaine_div ds ax, 0 TPfini ds ax, 1 ;mettre DX 0 pour la division ;diviser DX:AX par BX ;pas de reste ? ;non ? alors pas premier ! ;restaurer le nombre dans AX ;on va diviser par le suivant ;si nouveau diviseur >= nombre ; alors le nombre est premier ! ;sinon recommencer ! ;restauration de DS ;restauration des reg. gnraux ;restauration des flags ;le nombre n'tait pas premier

TPprochaine_div: xor div cmp je mov inc cmp jae jmp TPnon_premier: pop popa popf mov jmp TPpremier: pop popa popf mov TPfini: ret TPsto_nombre test_prem endp ;********** donnes ici ********** dw ? ;retour l'appelant ;pour garder le nombre tester ;restauration de DS ;restauration des reg. gnraux ;restauration des flags ;le nombre tait premier ;-)

Macro qui crit un entier l'cran


comment * Macro qui crit un entier l'cran Paramtres : AX = nombre crire Rsultat : cran... * ecrit_ent macro local .386 pushf pusha mov push mov boucle1: xor div push or jnz boucle2: pop cmp je add xchg mov int xchg jmp termine: popa popf endm ;restauration des reg. gnraux ;restauration des flags ax ax, 0BEBEh termine al, '0' al, dl ah, 02h 21h dl, al boucle2 dx, dx bx dx ax, ax boucle1 boucle1, boucle2, termine ;doit tre la premire ligne ! ;sauvegarde des flags ;sauvegarde des reg. gnraux dx, 0BEBEh dx bx, 10 ;empiler le mot BEBEh ; (comme repre) ;on va diviser par 10 ;pour trouver les chiffres ;mettre DX 0 pour la division ;diviser ! ;empiler un chiffre ;a-t-on fini ? ;boucler sinon ! ;boucle pour l'affichage ;obtenir un chiffre ;est-ce la fin ? ;oui ? alors quitter ! ;ajouter le code ASCII '0' ;mettre dans DL ;crire un caractre ; l'cran ! ;restaurer DL ;prochain chiffre

Macro qui fait revenir le curseur de lcran la ligne

comment * Macro qui fait revenir la ligne Paramtres : aucun Rsultat : cran... * ligne macro fin_de_ligne retour_chariot push ax dx mov mov int mov int pop endm equ equ 10 13 ;code ASCII 10 : LF ;code ASCII 13 : CR ;sauvegarder AX et DX ;crire un caractre ;caractre fin de ligne ;zou ! ;caractre retour chariot ;zou ! ;restaurer AX et DX

ah, 02h dl, fin_de_ligne 21h dl, retour_chariot 21h dx ax

Macro qui lit une chane de caractres au clavier


comment * Macro qui lit une chane de caractres au clavier Paramtres : offset d'un buffer (par rapp. DS) pour le rsultat Rsultat : dans le buffer pass en paramtre * lit_chaine macro push mov mov mov int pop endm buffer? ax dx ah, 0Ch al, 0Ah dx, buffer? 21h dx ax ;stocker ax et dx ;la fonction 0Ch ; appellera la 0Ah ;adresse du buffer ;zou ! ;restaurer dx et ax

3) Programmes COM Programme COM qui crit l'cran les noms des fichiers et dossiers du rpertoire courant
comment * Programme qui crit l'cran les noms des fichiers et des dossiersdu rpertoire courant (sans les fichiers cachs,...) Paramtres : aucun Remarque : la macro ligne utilise dans ce programme na pas t rcrite. Il vous suffit de la copier-coller ! * code segment assume org .386 dossiers debut: mov mov mov chercher: int jc taille_nom: push mov xor mov repne sub neg mov concat_$: mov ecrire_nom: mov mov int ligne suivant: pop dx cx ;restaure masque et attrib ah, 9h dx, 80h + 1Eh 21h ;crire une chane ;offset de la chane ;zou ! ;revenir la ligne byte ptr [80h + 1Eh + bp], '$' ;ajouter le caract. $ cx dx cx, 13 al, al di, 80h+1Eh scasb cx, 12 cx bp, cx ;sauvegarderattrib et masque ;taille max + 1 du nom ;car. recherch : 00 terminal ;dpart (cf structure DTA) ;chercher le 00 terminal ;dduire la ; longueur du nom du fichier ; et la ranger dans bp 21h terminer ;cestparti ! ;si aucun fichier dx, offset masque cx, dossiers ah, 4eh ;masque de recherche ;attriburs de recherche ;pour trouver le premier use16 cs:code, ds:code, es:code, ss:code 100h equ 00010000b ;attributs normaux + dossiers

mov jmp terminer: ret masque code enddebut db

ah, 4fh chercher

;pour trouver suivant ;allons-y ! ;rendre la main au systme ;masque (rech.) + 0 terminal

;********** donnes ici ********** "*.*", 0 ends

Programme COM qui crit l'cran les 20 premiers nombres premiers


comment * Programme qui crit l'cran les 20 premiers nombres premiers Paramtres : aucun Remarque : la macro ecrit_ent et la procdure test_prem utilises dans ce programme nont pas t rcrites. Il vous suffit de les copier-coller ! * title .386 code segment assume org combien espace debut: mov mov prochain: mov call cmp je mov ecrit_ent + mov mov int dec vers_prochain: jcxz inc jmp fini: ret code ends end debut ;on a fini fini bx prochain ;tester si CX = 0 ;pour tester le suivant ;on va le tester, ce suivant ! ah,02h dl, espace 21h cx ;crire un caractre ;un espace ;zou ! ;un de moins crire ! ax, bx test_prem ax, 0 vers_prochain ax, bx ;nombre tester dans AX ;est-il premier ? ;tester : si non premier ; alors passer au prochain ;sinon restaurer nombre ;crire nombre bx, 0 cx, combien ;on teste partir de 0 ;nombre de nombres afficher ecrit20prem use16 cs:code, ds:code, es:code, ss:code 100h equ equ 20 ;combien de premiers afficher ? ;code ASCII de lespace (32)

4) Programmes EXE Programme EXE qui calcule la somme des n premiers entiers et qui lcrit l'cran
comment * Programme qui crit l'cran la somme des n premiers entiers naturels (n tant une constante). Paramtres : aucun Remarque : la macro ecrit_ent utilise dans ce programme na pas t rcrite. Il vous suffit de la copier-coller ! * code segment assume org .386 combien debut: xor mov cmp je encore: add ax, cx ;sinon on ajoute CX ax, ax cx, combien cx, 0 fin_boucle ;accumulateur = 0 ;pour le LOOP ;cas part. : somme de 0 entiers ;dans ce cas on sort use16 cs:code, ds:code, ss: pile 100h equ 20 ;somme de combien dentiers ?

loop fin_boucle: ecrit_ent mov int ends

encore

;et on LOOPe ;crire le rsultat

ah, 4ch 21h

;pour quitter ;quitter ! ;segment de pile

code pile pile

segment stack db 256 dup(?) ends end debut