2010-03-30 14 views

Répondre

3

Cela dépend de l'ABI et de l'architecture, mais si l'adresse de retour se retrouve sur la pile, c'est l'effet secondaire de l'instruction call qui l'y place.

5

Idéalement, la déclaration call devrait prendre soin de cela. L'emplacement suivant du compteur de programmes sera poussé dans la pile. Lorsque la fonction (sous-routine) qui a été appelée l'a terminée, elle fonctionne et quand elle rencontre une déclaration de retour, le contrôle va maintenant à l'adresse qui a été poussée dans la pile et elle sera sautée.

+1

COMMEnT 'call' accord avec elle alors? Je veux juste voir où l'* adresse ret * est spécifié – Mask

+0

Vous devrez décomposer la méthode d'appel pour poursuivre le code hexadécimal. La feuille de triche pour l'ensemble d'instructions spécifié pour le processeur particulier révélerait cela. Par exemple si vous prenez le plus simple des microprocesseurs 8085 et l'instruction ADD X ne montrera pas la deuxième valeur (supposons Y comme ADD X, Y). Au lieu de cela, il ajoutera la valeur X à un registre réservé dans le processeur, par exemple H, et mémorisera la valeur dans H. Le bit de débordement devrait être stocké dans un autre registre. C'est ainsi que l'instruction ADD est conçue. L'instruction CALL aura également des règles prédéfinies similaires – bragboy

+5

Une partie du travail de l'instruction d'appel consiste à pousser l'adresse de retour sur la pile. L'adresse de retour est juste l'adresse directement après les paramètres de l'instruction d'appel. Pour voir quelle est l'adresse de retour dans votre exemple ci-dessus, vous devez regarder la pile dès que le programme entre dans la procédure à 0x4012d0. –

4

Sur un processeur x86 (comme pour votre exemple de langage d'assemblage), l'instruction call repousse l'adresse de retour sur la pile et transfère le contrôle à la fonction.

Toutes les architectures de processeur ne placent pas l'adresse de retour sur la pile - il existe souvent un ensemble d'un ou plusieurs registres conçus pour contenir les adresses de retour. Sur les processeurs ARM, l'instruction BL place l'adresse de retour dans un registre spécifique (LR ou le 'registre de liens') et transfère le contrôle à la fonction. Le processeur ia64 fait quelque chose de similaire, sauf qu'il y a plusieurs registres possibles (b0 - b7) qui peuvent recevoir l'adresse de retour et un sera spécifié dans l'instruction (b0 étant la valeur par défaut).

1

appel pousse la valeur actuelle du registre de RIP (adresse de retour) de la pile + fait l'appel
ret affiche l'adresse de retour (ce appel poussée) à partir du sommet de la pile (RSP enregistrer des points ici) et l'écrit dans le registre RIP. Exemple sur une boîte GNU/Linux: la fonction f appelle la fonction g et regarde la trame de g.

ADRESSE BASSE

... < - RSP (pointeur de pile montre haut de la pile) enregistrer des points à cette adresse
vars locales g
pointeur de base de f (ancienne valeur RBP) < - RBP (pointeur de base) inscrire des points à cette adresse
f adresse de ret (ancienne valeur RIP) (ce que l'appel (de f) poussé, et ce que le ret (de g) sautera)
args que f appelé g avec et ne rentre pas dans les registres (je pense que sur Windows c'est différent)
...

ADRESSE HAUTE

g libérera les vars locales (movq% RÉR,% RBP)
g sauteront le "vieux RBP" et le stocker dans le registre RBP (pop% RBP)
g sera ret, qui modifiera RIP avec la valeur qui est stockée où les points RER à

Hope it helps