les procedures et fonctions en assembleur du 80386
puisse DIEU nous aider a réussir Sni* to View Filière: SYSTEME ELE CLASSE 1ère ANNÉE sommaire Introduction….. …………. 2 o OR TIQUE I-programmation d’une procédure.. Il-Programmation d’une fonction…. … 6 conclusion…. 8 Le but de notre exposé est de faire la même chose en assembleur. Pour cela, on implémentera plusieurs morceaux de codes pour valider l’aspect théorique du tutoriel. pour mener à bien ce projet, nous verrons comment programmer une procédure/fonction, comment l’appeler, puis nous nous intéresserons à un bête exemple de programme (valide) pour ésumer tout ça.
I-Programmation d’une procédure Une procédure est amenée à être appelée, donc, tout d’abord, elle doit être identifiée. Nous l’identifierons par un « label ». Code : asm Maprocedure: ; le label du code Supposons que cette procédure n’attende aucun argument. Ce qu’elle doit tout de même faire, c’est sauvegarder l’état de la pile après son appel pour ne pas la modifier. pour cela, elle se sert des instructions suivantes . push ebp mov ebp, esp Ce jeu d’instructions sert à sauvegarder la base de la pile au sommet, puis de faire une pile « vide » au-dessus de nos auvegardes : ebp = esp, la pile fait O octets.
Des schémas pour mieux comprendre : Etat de la pile après un push eb pile vide. Après avoir fait tout son travail, la procédure utilisera l’instruction « leave », qui aura pour but de mettre la valeur d’esp dans l’ebp de la fonction. On aura temporairement ebp « au-dessus » d’esp. Soit une pile à l’envers. Cependant, il y aura, au sommet de la pile sens dessus dessous, notre sauvegarde d’ebp. On n’a plus qu’à la dépiler dans ebp lui-même pour que notre pile soit restaurée. Enfin, on fait un ret pour revenir au programme principal.
Résumons le code d’une procédure : Maprocedure: le ave Voyons maintenant comment un programme principal appellera cette procédure : start: ; point d’entrée du programme instructions ; instructions . call MaProcedure ; instructions Oui. Il suffit de faire un bête « call Label » pour appeler une fonction. Quelle est la différence en aut inconditionnel) et un après le leave. Le leave restaure la pile ; on a donc, normalement, notre sauvegarde au sommet. On restaure la sauvegarde et on revient à la routine appelante. Cest aussi simple que ça. Tout cela vaut aussi pour les fonctions.
Il-Programmation d’une fonction Comme je le disais, une fonction, à l’inverse d’une procédure, ça retourne une valeur. La fonction aura ce code MaFonction: ; du code… leave Sauf qu’elle ne retourne pas de valeur, ici. Pour retourner une valeur, la fonction doit placer cette valeur dans le registre eax. C’est la convention. mov eax, 1 ; la fonction va retourner « 1 » en valeur. Et ça sera au programme princi al de récupérer cette valeur dans registre si vous ne voulez pas perdre son ancienne valeur. Je rappelle la fonction carre en C : code : C Void carre(int n) { return n*n;
Supposons que nous voulions obtenir le carré du nombre 5 : ; notre fonction carre carre: , L’argument se retrouve en-dessous de la sauvegarde d’eip, ; puis qu’il a été empilé avant. Logiquement, on a une pile ; dont ebp = esp et ces valeurs pointent sur la sauvegarde d’ebp. ; Donc, pour notre argument se retrouve = esp + 4 (sauvegarde d’ebp) ; + 4 (sauvegarde d’eip) = 8. mov eax, [esp+8] ; place dans eax le contenu pointé par esp+8 ; l’instruction « mull’ nia besoin que d’une opérande ; en effet, ; elle va multiplier cette opérande au contenu d’eax. Cette ; instruction ne modifiera que le contenu d’eax. l eax ; multiplie à eax sa propre valeur, soit eax = eax * eax leave ; restaure la pile ; revient à la routine principale start: push 5 ; on empile l’ar carre , Donc, pour notre argument se retrouve = esp + 4 ; l’instruction « mull’ nia besoin que dune opérande ; en effet, ; instruction ne modifiera que le contenu dieax. push 5 ; on empile l’argument call carre ; on appelle la fonction ; là, on a eax = 25 (normalement :p) , On push eax qui correspondra à la donnée formatée par le push eax ; On push la phrase push offset Phrase ; On call printf call crt_printf ; on quitte le proeram