ASM - Utilisation des registres EBP, ESP, SS

Résolu/Fermé
Stratosphr - 23 avril 2011 à 11:00
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
- 26 juil. 2011 à 06:56
Bonjour, après avoir lu quelques tutoriels sur l'assembleur, j'aimerais vérifier certaines choses concernant ces trois registres : EBP, ESP, SS.

1ère question : le programme qui suit est-il "propre" et "correct" ? Ais-je le droit d'utiliser directement EBP et [EBP-4] sans initialisation ?

PROGRAMME :

segment .text
global asm_main

asm_main:
MOV dword[ebp], 0
MOV dword[ebp-4], 64
LEAVE
RET


Merci d'avance pour vos réponses :)

7 réponses

nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
140
Modifié par nicocorico le 26/07/2011 à 05:51
J'ai bien vu que le sujet est résolu, mais j'aimerais apporter une petite précision;
Enter et leave sont l'équivalent de ces instructions :
     
PUSH    EBP                   
MOV     EBP,ESP              
SUB      ESP,Locals         
...     
code        
 ...     
MOV     ESP,EBP               
POP     EBP        

Permettant de créer un cadre de pile standard basé sur EBP;
D'une part, les instructions enter et leave sont extrêmement lentes, très loin du temps d'exécution de la suite d'instructions équivalentes, d'autre part il est possible d'utiliser la pile en soustrayant à ESP la taille escomptée et en l'ajoutant à la fin de la fonction, et en utilisant ESP comme ceci :
Sub ESP,08;     

Mov  [ESP],EAX;  // Variable dword 1      
Mov  [ESP+04],EAX;  // 2ème variable dword      

Add  ESP,08;  // Rétabli la pile de l'appelant     

Ce qui permet d'utiliser EBP à d'autres fins et c'est beaucoup plus rapide, mais il faut faire attention au push et pop dans la fonction, qui décalent les variables sur la pile, ainsi que les éventuels paramètres empilés de la fonction)...
2
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
140
Modifié par nicocorico le 26/07/2011 à 07:24
Ultime précision sur Enter et l'imbrication :
Lorqu'on appelle Enter, chacunes des fonctions imbriquées sauvegardent EBP sur la pile, enregistrant par là-même le pointeur du cadre de pile de la fonction appelante, donc chaque fonction peut accéder au cadre de pile de la fonction appelante en lisant le contenu de [EBP]; Et si on appelle Enter avec 1 en second paramètre, la procédure recopie la valeur présente en [EBP] avant de sauvegarder EBP à son tour et de le fixer sur le nouveau cadre de pile;
On a donc maintenant le cadre de pile de l'appelante en [EBP] et le cadre de pile de l'appelante de l'appelante en [EBP + 04]... Et ainsi de suite en fonction du niveau d'imbrication;
Ce tableau étant élargi à chaque niveau d'imbrication, on peut alors accéder à l'ensemble des paramètres et locales de l'ensemble des fonctions appelantes, sans avoir à repasser les paramètres similaires de fonctions en fonctions... Puissant, non ?

Le chêne aussi était un gland, avant d'être un chêne
0
Je me permet de faire un UP étant donné que c'est un sujet qui risque de trouver peu de réponse :$
0
ghuysmans99
Messages postés
2493
Date d'inscription
jeudi 14 juillet 2005
Statut
Contributeur
Dernière intervention
5 juin 2016
334
Modifié par ghuysmans99 le 24/04/2011 à 00:33
Normalement tu ne peux pas : EBP a été affecté par la fonction appelante (runtime C) et tu es en train de massacrer sa partie de stack. Si tu veux te créer des variables locales, fais comme ceci :
asm_main: 
enter 8,0 
mov dword [ebp-4], 0 
mov dword [ebp-8], 64 
leave 
ret

EDIT: dword [ebp-4] c'est bon en fait. Confusion avec les paramètres ...
Google is your best friend
VB.NET is good ... VB6 is better !
0
Merci beaucoup :)
J'ai regardé ce qui se disait sur "enter".
Le premier paramètre me permet d'indiquer le nombre d'octets que je souhaite utiliser, c'est bien ça ? Jusque là, pas de problème.
Le second... fixe le niveau d'imbrication de la procédure ? Je pense comprendre à peu près... Mais j'aimerais plus d'informations... J'ai vu qu'effectivement, dans les conventions d'appel du C, on mettait toujours 0. Une explication serait cependant la bienvenue...
Une dernière chose, pourquoi commencer l'assignation à [ebp-8] et pas [ebp-4] par exemple ?
Est-ce que les 8 premiers octets sont réservés ou quelque chose dans ce genre là ? Je pense d'après ce que je viens de lire, que [ebp] ne peut pas être modifiée ou doit au moins être restaurée à sa valeur d'origine avant la fin du programme. Mais pour [ebp-4] ?
Merci encore pour votre réponse :)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ghuysmans99
Messages postés
2493
Date d'inscription
jeudi 14 juillet 2005
Statut
Contributeur
Dernière intervention
5 juin 2016
334
25 avril 2011 à 11:54
(Tu peux me tutoyer, y'a pas de raison que je sois le seul à le faire). Un petit peu plus d'explications sur ENTER : http://www.posix.nl/linuxassembly/nasmdochtml/nasmdoca.html#section-A.27. Perso je comprends pas trop à quoi ça sert et je n'ai jamais vu un programme qui se servait de la 2ème opérande ...

On dirait que tu n'as pas très bien compris comment fonctionne l'appel de fonctions avec paramètres et stackframe ... Pas grave, je t'explique.
On utilise principalement la pile lorsqu'on veut appeler des fonctions. Cette pile commence à partir du bout de la mémoire et va en descendant. Dans l'archi x86, on ne peut pas empiler autre chose que 4 octets (int, pointeur) via l'instruction push. Le pointeur de pile ESP indique où se trouve le dernier élément de la pile en mémoire et EBP sert dans les fonctions à accéder facilement aux paramètres et aux variables locales (s'il y en a). Lorsqu'on fait un CALL, le processeur empile l'adresse de retour (=adresse de l'instruction qui suit le CALL) et saute à l'adresse de la fonction. Pour quitter la fonction, on fait un RET qui dépile la dernière adresse sur la pile et saute à celle-ci. Pour appeler une fonction en ASM, on fait ça http://img20.imageshack.us/img20/489/appelfct.png : on empile les paramètres dans l'ordre inverse et on appelle la fonction. Il y a donc ça sur la pile lorsqu'on rentre dans celle-ci (la pile avance vers le haut) : http://img96.imageshack.us/img96/3955/stackappel.png. On n'a toujours pas réservé de la place pour les locales ... Pour ce faire, il faut sauver EBP, y mettre l'adresse contenue dans ESP et retirer n octets à ESP pour les locales (voilà ce que fait ENTER n, 0). Le stack devient donc comme ceci http://img193.imageshack.us/img193/9603/stackvarlocales.png. Il est donc logique que la première variable locale ne se trouve pas en ebp car il y a à cette adresse le contenu de l'ancienne valeur d'EBP ...

Si y'a un truc que tu ne comprends pas dans ce pavé, n'hésite pas ...
0
Tu ne devrais pas toucher ni a [ebp] ni à [ebp-4] car ils stockent respectivement (si je me souviens bien) l'adresse de ta fonction et l'adresse de retour. Donc si tu modifie [ebp-4] tu fera planter ton programme lorsque tu appelera ret.

Utiliser enter est la bonne solution. Si tu code sous MASM tu peux utiliser le mot clé LOCAL.

SS est le segment de pile. C'est généralement le même que CS et DS, ça dépend du programme.

Quelle est ta deuxième question?
0
ghuysmans99
Messages postés
2493
Date d'inscription
jeudi 14 juillet 2005
Statut
Contributeur
Dernière intervention
5 juin 2016
334
Modifié par ghuysmans99 le 25/04/2011 à 12:26
ils stockent respectivement l'adresse de ta fonction et l'adresse de retour
L'adresse de la fonction ne se trouve pas sur le stack ! Regarde mon dernier lien. Il ne code pas sous MASM vu qu'il est sous Linux et on se fiche complètement des segments ici (on est en 32 bits et on ne fait pas de prog système)
0
Ah oui, oups, je me suis trompé, c'est bien l'emplacement du frame précédent qui est à [ebp].
0
Merci à vous deux pour les infos, les liens, et le pavé ! (Au moins je vois que je ne suis pas le seul à m'intéresser à l'assembleur ^^) Je comprends qu'ENTER remplace une série d'instructions ASM qui reviennent très souvent dans les programmes que j'ai regardé. Je comprends aussi à présent pourquoi ces instructions sont utilisées, et je t'en remercie.
Ma deuxième question, la voici :
j'ai désassemblé un fichier objet (avec objdump et également gdb).
Cette instruction n'est pas claire pour moi :
MOV $0x1c, %eax
Je vois qu'il semble y avoir une adresse hexadécimale mais à quoi correspond-elle exactement ?
0
"MOV $0x1c, %eax " c'ets la syntaxe AT & T ça correspond à "mov eax, 01Ch"
Dans la syntaxe AT&T, le modèle est "opérande source, destination" et on ajoute un % devant un nom de registre et $ devant une constante que l'on écrit 0xvaleur et non valeurh.
0
ghuysmans99
Messages postés
2493
Date d'inscription
jeudi 14 juillet 2005
Statut
Contributeur
Dernière intervention
5 juin 2016
334
27 avril 2011 à 00:37
Le désassembleur t'a produit un code en syntaxe AT&T (inversion dst<->src, préfixes obligatoires pour chaque truc). En syntaxe Intel, ça donne mov eax,0x1C
0
Merci finalement j'ai fini par trouver la réponse hier.
Mais cela ne me dit toujours pas quelle est cette adresse... 0x1C, c'est de l'hexadécimal, ça OK.
Que représente alors l'adresse 0x0 ? Est-ce qu'on a le droit de choisir arbitrairement un emplacement mémoire ? J'en doute...
0
ghuysmans99
Messages postés
2493
Date d'inscription
jeudi 14 juillet 2005
Statut
Contributeur
Dernière intervention
5 juin 2016
334
27 avril 2011 à 22:55
C'est pas une adresse mais une valeur (préfixe $). L'adresse 0x0 ne représente rien du tout, et essayer d'y accéder c'est être sûr que le programme se fera tuer par l'OS pour violation de mémoire. Tu pourrais choisir tes adresses en bidouillant un peu mais quel intérêt ?
0
Merci de m'avoir éclairé. J'ai l'impression d'apprendre un nouveau langage à chaque code source que je regarde ^^ Je vais tâcher de relire quelques tutoriels sur l'assembleur avant de continuer à faire du grand n'importe quoi en pensant avoir compris. J'avais besoin de ces explications. Merci à toi !
0
Je te conseil de changer de debogueur. Moi perso je trouve que OllyDbg est très bien. Ce sera beaucoup plus lisible.
0
fiddy
Messages postés
11067
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 811
29 avril 2011 à 22:57
OllyDbg sur GNU/Linux ??? Il n'est que sur windows à ma connaissance...
0