L'alignement de pile avec malloc
Fermé
Mordekeiser
Messages postés
156
Date d'inscription
samedi 31 octobre 2015
Statut
Membre
Dernière intervention
3 juillet 2018
-
30 juin 2018 à 11:37
Mordekeiser Messages postés 156 Date d'inscription samedi 31 octobre 2015 Statut Membre Dernière intervention 3 juillet 2018 - 3 juil. 2018 à 11:36
Mordekeiser Messages postés 156 Date d'inscription samedi 31 octobre 2015 Statut Membre Dernière intervention 3 juillet 2018 - 3 juil. 2018 à 11:36
A voir également:
- L'alignement de pile avec malloc
- Pile carte mere - Guide
- L'accu pile est déchargé nikon coolpix - Forum Nikon
- Impossible de créer une nouvelle page de garde pour la pile - Forum Windows 10
- Pile bios empêche démarrage pc - Forum BIOS
- Alignement tête de lecture magnétoscope - Forum Lecteurs et supports vidéo
1 réponse
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
3 juil. 2018 à 07:36
3 juil. 2018 à 07:36
Bonjour,
Il est tout à fait possible de soustraire la taille des données au fur et à mesure oui, c'est à dire que dans ce cas on utilise tout simplement l'empilement, à la manière d'un push (si ce n'est qu'il se fait sur esp):
Un push équivaut à:
Sub esp,04
Mov [esp],04
Il faut savoir que le registre esp pointe toujours à l'endroit judicieux concernant le programme en cours (le notre en l'occurence) car s'il y a une interruption il est sauvegardé puis restauré.
C'est à dire que le simple fait d'ajouter 16 au pointeur de pile esp, réserve 16 octets pour notre programme jusqu'à ce qu'on ajoute 16 pour les libérer. C'est exactement ce que fait un Push suivi d'un Pop, ou un Call suivi d'un Ret (l'un sauvegardant l'adresse de retour sur la pile et l'autre la dépilant pour savoir ou revenir).
Donc toute utilisation de pile se fait en réservant une portion mémoire, qu'on libère ensuite dans l'ordre exactement inverse.
Elle s'utilise à l'envers car de cette manière esp pointe systématiquement sur le début du bloc qu'on vient de réserver, sinon il pointerait sur la fin du bloc.
L'utilisation du cadre de pile avec ebp est une convention, en pratique on peut très bien utiliser tout autre registre en cadre de pile.
Le cadre de pile fondé sur ebp à pour intérêt de stabiliser l'adresse du bloc réservé, car esp est modifié par les opérations sur pile tels que les push ou les call, ce qui est vite gênant dans une lognue routine compliquée.
Cependant dans une routine simple le cadre de pile n'a pas vraiment d'intérêt, on peut très bien utiliser esp directement. Par exemple il est parfois utile de sauvegarder une valeur avec un push et l'utiliser à plusieurs reprises, pour ce faire on peut la relire avec (ex: mov eax,[esp] ) sans la dépiler.
Ou bien il est possible de se passer des push et des pops en prévoyant de stocker toutes les valeurs sauvegardées dans un enregistrement sur pile, que l'on réserve en soustrayant sa taille à esp.
Le plus gênant c'est l'appel de fonction, car dans ce cas la fonction appelée ne peut pas accéder aisément aux variables sur pile réservées par la fonction appelante puisque esp a été décalé de -4 ou -8 par le Call.
Sinon l'accès avec cadre de pile se fait ainsi:
push ebp
mov ebp, esp
sub ESP, 8 ; c'est sur esp qu'il faut réserver la taille totale
mov dword [ebp-4], 76 ; 1ère valeur
mov dword [ebp-8], 24 ; 2ème valeur
Par ailleurs on peut très bien faire le mov ebp,esp après ajustement, ainsi on pointe simplement sur l'enregistrement:
push ebp
sub ESP, 8 ; c'est sur esp qu'il faut réserver la taille totale
mov ebp, esp
mov dword [ebp], 76 ; 1ère valeur
mov dword [ebp+04], 24 ; 2ème valeur
J'ai inversé l'ordre des valeurs pour être plus logique)
Il est tout à fait possible de soustraire la taille des données au fur et à mesure oui, c'est à dire que dans ce cas on utilise tout simplement l'empilement, à la manière d'un push (si ce n'est qu'il se fait sur esp):
Un push équivaut à:
Sub esp,04
Mov [esp],04
Il faut savoir que le registre esp pointe toujours à l'endroit judicieux concernant le programme en cours (le notre en l'occurence) car s'il y a une interruption il est sauvegardé puis restauré.
C'est à dire que le simple fait d'ajouter 16 au pointeur de pile esp, réserve 16 octets pour notre programme jusqu'à ce qu'on ajoute 16 pour les libérer. C'est exactement ce que fait un Push suivi d'un Pop, ou un Call suivi d'un Ret (l'un sauvegardant l'adresse de retour sur la pile et l'autre la dépilant pour savoir ou revenir).
Donc toute utilisation de pile se fait en réservant une portion mémoire, qu'on libère ensuite dans l'ordre exactement inverse.
Elle s'utilise à l'envers car de cette manière esp pointe systématiquement sur le début du bloc qu'on vient de réserver, sinon il pointerait sur la fin du bloc.
L'utilisation du cadre de pile avec ebp est une convention, en pratique on peut très bien utiliser tout autre registre en cadre de pile.
Le cadre de pile fondé sur ebp à pour intérêt de stabiliser l'adresse du bloc réservé, car esp est modifié par les opérations sur pile tels que les push ou les call, ce qui est vite gênant dans une lognue routine compliquée.
Cependant dans une routine simple le cadre de pile n'a pas vraiment d'intérêt, on peut très bien utiliser esp directement. Par exemple il est parfois utile de sauvegarder une valeur avec un push et l'utiliser à plusieurs reprises, pour ce faire on peut la relire avec (ex: mov eax,[esp] ) sans la dépiler.
Ou bien il est possible de se passer des push et des pops en prévoyant de stocker toutes les valeurs sauvegardées dans un enregistrement sur pile, que l'on réserve en soustrayant sa taille à esp.
Le plus gênant c'est l'appel de fonction, car dans ce cas la fonction appelée ne peut pas accéder aisément aux variables sur pile réservées par la fonction appelante puisque esp a été décalé de -4 ou -8 par le Call.
Sinon l'accès avec cadre de pile se fait ainsi:
push ebp
mov ebp, esp
sub ESP, 8 ; c'est sur esp qu'il faut réserver la taille totale
mov dword [ebp-4], 76 ; 1ère valeur
mov dword [ebp-8], 24 ; 2ème valeur
Par ailleurs on peut très bien faire le mov ebp,esp après ajustement, ainsi on pointe simplement sur l'enregistrement:
push ebp
sub ESP, 8 ; c'est sur esp qu'il faut réserver la taille totale
mov ebp, esp
mov dword [ebp], 76 ; 1ère valeur
mov dword [ebp+04], 24 ; 2ème valeur
J'ai inversé l'ordre des valeurs pour être plus logique)
3 juil. 2018 à 11:36