;;;Auteur = Younes El Amrani ;;;Premiere Modification = mercredi, 27 juin 2007 ;;;Premiere Revision = samedi, 24 avril 2009 ;;;bubble.asm tri un tableau d'entier. Les tri utilise est bubble extern _printf ; importe _printf global _main ; exporte _main ;;; macro qui appelle la fonction printf de la bibliotheque C ;;; utilisation : print format, valeur/adress %macro print 2 push %2 push %1 call _printf add esp, 8 %endmacro ;;; Macro qui effectue le swap du contenu de deux adresses en mémoire ;;; Utilisation : swap dword [v1], dword [v2] %macro swap 2 push eax push ebx mov eax, %1 mov ebx, %2 mov %2, eax mov %1, ebx pop ebx pop eax %endmacro %macro swapv2 2 push %1 push %2 pop %1 pop %2 %endmacro ;;; Macro qui permet l'affichage d'un tableau d'entiers. Les separer par un espace ;;; Utilisation: printArray array, taille ; taille est la taille du tableau %macro printArray 2 push esi mov esi, 0 ;;; la notation %%label, permet de generer un label unique a chaque utilisation de la macro %%IMPRIMER_SUIVANT: print integerFormat, DWORD [ %1 + (esi * 4) ] ; Afficher un entier du tableau print stringFormat, whiteSpace ; Separer les entiers par un espace inc esi cmp esi, %2 jl %%IMPRIMER_SUIVANT pop esi %endmacro ;;; tableau is the name of the location of the array to be sorted ;;; taille is the number of elements of the array segment .data tableau dd 12,45,56,99,10,11,12,2,13,4,15,5,1,16,14,7,17,8,18,6,9,19,20,0,3, 100, 32, 44, 55 taille: EQU ($ - tableau) / 4 newLine: db 13, 10, 0 whiteSpace: db " " , 0 stringFormat: db "%s" , 0 integerFormat: db "%d" , 0 ;;; donnees non initialisees segment .bss ;;; Instructions executables du programme. _main est le point d'entree du code. segment .text _main: enter 0, 0 pusha pushf ;;; On affiche le tableau AVANT le tri printArray tableau, taille; on afficher les elements du tableau print stringFormat, newLine; on saute une ligne apres l'affichege ;;; On met dans edx le nombre N de passes. N = taille du tableau. mov edx, taille .NOUVELLE_PASSE: mov esi, 0 ; esi sert a indexer les elements du tableau mov edi, taille - 1 .CONTINUER_PASSE: mov eax, dword [tableau + (esi*4) ] ; eax = tableau[ esi*4 ] cmp eax, dword [tableau + ((esi + 1)*4)] ; on compare eax avec tableau[(esi+1)*4] jle .SWAP_INUTILE ; si ( tableau[ esi*4 ] < tableau[(esi+1)*4] ) sauter swap swap dword [tableau + (esi*4)] , dword [tableau + ((esi + 1)*4)]; sinon swaper .SWAP_INUTILE: inc dword esi ; on passe a la comparaison suivante cmp esi, edi ; On fait edi comparaison jl .CONTINUER_PASSE ; on continue si esi < edi dec dword edi ; L'élément à l'extrême droite du tableau est déjà classé dec edx ; on demarrera éventuellement une nouvelle passe si edx > 0 cmp edx, 0 ; on fait taille passes au plus jg .NOUVELLE_PASSE ; on repart pour une nouvelle passe ;;; On Affiche le tableau APRES le tri printArray tableau, taille print stringFormat, newLine popf popa mov eax, 0 leave ret ;;; Au lieu d'utiliser la macro printArray, on pourrait utiliser la fonction suivante: ;;; La macro printArray s'inspire de ce code. print_array_taille: enter 0, 0 push esi ; se servir de esi pour compter les element affiche mov esi, 0 .AFFICHE_SUIVANT: print integerFormat, DWORD [ tableau + (esi * 4) ]; afficher un element du tableau print stringFormat, whiteSpace ; separer les elements par un espace inc esi ; compter les elements deja affiche cmp esi, taille ; si on a pas tout affiche jl .AFFICHE_SUIVANT ; alors afficher le suivant pop esi ; sinon, on a fini de tout afficher, on restaure esi leave ret