Exercice assembleur x86 occurence d'un caractère

Dernière mise à jour le 16 novembre 2009 à 13:14 par marlalapocket
Publié par kilian



Introduction


Ce petit exercice d'assembleur vise les architectures x86 (Processeurs Intel et Amd 32 bits) et utilise la syntaxe de Nasm, un assembleur libre, gratuit et utilisable sur différentes plateformes telles que Windows ou Linux.
De même les fonctions externes utilisées sont issues de la bibliothèque C standard.

Ainsi vous n'aurez pas de problèmes liés à votre machine pour faire cet exercice: il n'est pas dépendant du système d'exploitation utilisé. Il est uniquement dépendant de l'architecture x86.

NOTE: Pour utiliser nasm afin de tester cet exercice, vous trouverez un tutoriel d'utilisation/installation de nasm pour Windows et Linux en cliquant ici.

Notions abordées dans cet exercice

  • Ecriture d'une fonction avec gestion des paramètres d'entrée
  • Gestion des tableaux

Enoncé


Imaginons un tableau de caractères (qui ne se termine pas nécessairement par 0). On possède sa taille et on voudrait pouvoir tester la présence d'un caractère donné dans ce tableau. Le but va donc être d'écrire une fonction qui prend en entrée un tableau de caractères, sa taille et un caractère. Si ce caractère est présent dans le tableau, on retourne une valeur différente de zero, sinon on retourne zero.

Voici ce que donnerait cette fonction en C:
//Le prototype de cette fonction
int est_dans_tableau(char *tableau, int taille, char c); 
//Exemple d'utilisation:
char tab[] = {'n', 'e', 'u', 'e'};
est_dans_tableau(tab, sizeof(tab), 'u'); //Retournera autre chose que 0
est_dans_tableau(tab, sizeof(tab), 'a'); //Retournera 0


Il vous faudra insérer ce code là dedans:
extern printf

section .data
	tableau db 'dadedidadedavivoufufifamasibifisaz'
	oui db 'oui', 10, 0
	non db 'non', 10, 0

section .text
	global main

est_dans_tableau:
	;Insérez votre code ici!!


main:
	push ebp
	mov ebp, esp
	
       ;On va tester si m est présent dans le tableau
	push dword 'm'
	;La longueur du tableau (ici 34) 
	push dword 34 
	;Adresse de chaine dans eax
	push tableau

        ;Appel de est_dans_tableau avec l'adresse du tableau, 
        ;sa taille, et la valeur à chercher
	call est_dans_tableau
	test eax, eax
	jnz est_dedans ;Si eax != 0 alors on affiche oui
	push non ;Sinon on affichera non
	jmp affichage
        ;Affichage de la chaine avec printf
   est_dedans:
	push oui
   affichage:
	call printf

	mov eax, 0
	leave
	ret


C'est parti! Reflechissez un peu quelques dizaines de minutes s'il le faut. Faites une recherche sur les instructions en rapport avec les chaines. Pas d'indice pour cet exercice :-)

Corrigé


Voici une solution:
est_dans_tableau:
	;On récupère l'adresse du tableau (premier paramètre) dans edi
	mov edi, [esp + 4] 
	;On récupère la taille du tableau (second paramètre) dans ecx
	mov ecx, [esp + 8]
	;On récupère le caractère à trouver (troisième paramètre) dans eax
	mov eax, [esp + 12]

	;Recherche du caractère
	repne scasb
	;Si le flag ZERO (ZF) est à 1 c'est qu'on a trouvé le caractère
	;Sinon c'est qu'on ne l'a pas trouvé
	;Il nous suffit donc de mettre la valeur de ZF dans eax
	mov eax, 0
	;Si ZF = 1 alors al = 1 (al étant les 8 bits de poid faible d'eax)
	setz al 

	ret

Explication


Le but était de vous faire utiliser la combinaison des instructions de type "rep" et "scas". Ici nous utilisons "repne". Cette instruction répète l'instruction qui la suit en faisant décrémenter ecx à chaque itération. Cette boucle s'arrête lorsque ecx = 0 ou lorsque le Flag Zero (ZF) est à 1. L'instruction scasb, quant à elle, recherche la présence d'un caractère (logé dans al, partie basse de eax) dans l'emplacement mémoire pointé par edi. Si al est égal à la valeur pointée par edi, alors le Flag Zero est mis à 1. Ensuite, dans tous les cas, edi est incrémenté de 1.
Voici donc ce qui se passe, vu que ce qui vient d'être expliqué ne doit pas être très parlant, avouons le :-)
ZF = 0
ecx = longueur
eax = caractère
edi = tableau
//Boucle qui représente le "repne scasb"
Tant que ecx != 0 ET ZF = 0 Faire
    Si al == [edi] Alors
        ZF = 1
    FinSi
    ecx = ecx - 1
    edi = edi + 1
FinTantQue

eax = 0
//Condition qui représente le "setz"
Si ZF = 1 Alors
    eax = 1
FinSi


Et voilà :-)
Meilleures réponses pour « Exercice assembleur x86 occurence d'un caractère » dans :
Exercice assembleur x86 inversion de chaîne Voir Introduction Notions abordées dans cet exercice Énoncé Rappel Indices Corrigé Explication Introduction Ce petit exercice d'assembleur vise les architectures x86 (Processeurs Intel et Amd 32 bits) et utilise la syntaxe de Nasm, un...
Liens utiles assembleur x86 Voir Voici quelques liens utiles pour l'assembleur x86. Le but étant de compiler des documents pertinents autant pour ceux qui débutent que pour ceux qui sont à l'aise dans ce domaine. Tutoriels Références complètes Assembleur sous...
Exercice assembleur x86 nombre premier VoirIntroduction Notions abordées dans cet exercice Enoncé Rappel Corrigé Explication Introduction Ce petit exercice d'assembleur vise les architectures x86 (Processeurs Intel et Amd 32 bits) et utilise la syntaxe de Nasm, un assembleur...
Compiler un programme assembleur avec Nasm VoirAvec Linux Etape 1. Créer un fichier source Etape 2. Assembler le fichier source Etape 3. Création de l'executable Etape 4. Execution du programme Avec windows Etape 1. Installer les logiciels nécessaires Etape 2. Créer un fichier...
Interfacer du code assembleur et du C VoirInterfacer du code assembleur et du C Introduction Appeler du code assembleur écrit dans un fichier source externe Avec Nasm (x86 uniquement) Compilation/Execution sous Linux Avec Gcc (multiplateforme) Introduction Si, à tout hasard,...
Télécharger ZSNES VoirSi vous avez toujours voulu d'un émulateur pour Super Nintendo, celui ci vous plaira sûrement ! ZSNES est un émulateur open source de super Nintendo. Il a été écrit avec l'assemblage x86, C et C++. Pour le plus grand bonheur de ceux qui utilisent...
Introduction à l'assembleur VoirLes prérequis nécessaires Le langage assembleur est très proche du langage machine (c'est-à-dire le langage qu'utilise l'ordinateur : des informations en binaire, soit des 0 et des 1). Il dépend donc fortement du type de processeur. Ainsi il...