Architecture Les conventions assembleur / C Comme l’assembleur peut appeler des fonctions du C, il peut être nécessaire de connaître quelques conventions pour appeler correctement ces fonctions et et récupérer un résultat. Nous ne verrons pas ici comment faire l’appel au C mais comment écrire une fonction qui suit la syntaxe du C (et pourrait donc être utilisé par gcc une fois compilée). Les fonctions / procédures En C, une fonction possède généralement une liste de paramètres et renvoi une valeur. En assembleur, cette valeur de retour est stockée dans le registre EAX, et les paramètres sont stockées dans la pile ESP. Exemple : _func: mov eax, [esp+4] … ret ... _start: push a call func … Si la fonction appelée est amenée à modifier différents registres utilisés en amont, il peut être nécessaire de créer une nouvelle pile en sauvegardant l’ancien état bas de la pile ( EBP ) et en créant un nouvel état. Cet état est ensuite retrouvé par l’instruction leave : _func: push ebp ; sauvegarde de l’état mov ebp, esp ; création du nouvel état ; example : modification de ecx, possiblement utilisé comme compteur de boucle donc push push ecx ; instructions - acces au paramètres par ebp plutot que esp mov ecx, [ebp+8] ... pop ecx leave ; restaure l’état précédent de la pile ret Exercices : (utiliser les convention) 1. Réalisez la conversion d’une chaîne de caractère (sans accent) en majuscule ­ Commencer par réaliser une fonction _majusculeLettre qui prend en paramètre une lettre et renvoie la majuscule correspondante. ­ Petite difficulté supplémentaire : réécrire la même fonction mais en faisant les traitements sur le registre ECX, puis en retournant la valeur dans EAX. 2. Créez une fonction qui inverse une chaîne de caractères. 3. Créez une fonction qui recherche le nombre d’occurrences d’une lettre dans une chaîne de caractères et renvoi ce nombre d’occurrences. Quelques rappels d’instructions La boucle for(i=0; i < v; i++) du C est un peu différente dans le sens ou elle décrémente un compteur de boucle qui est le registre ECX : mov ecx, v ; valeur maximal de l’iterateur ( i = v) etiquette_boucle_for : ; instructions loop etiquette_boucle_for ; Si ECX != 0, decrémente ECX De manière un peu différente, il est possible de réaliser une boucle while en utilisant un registre comme itérateur et un jmp pour relancer la boucle : mov ecx, v ; valeur maximal de l’iterateur ( i = v) etiquette_boucle_while : ; instructions cmp ecx, 0 jge etiquette_boucle_while ; Si ECX >= 0, on reboucle Le if( … ){ }else{ } peuvent également se formaliser de la sorte : cmp registre,valeur jcc etiquette_si ;saut conditionnel (jbe, jge etc. voir quickcard) etiquette_sinon: ;instructions sinon jmp etiquette_finsi etiquette_si: ;instructions etiquette_finsi: ;suites du programme