Sujet TP4 - Conventions Assembleur / C

publicité
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
Téléchargement