2016-03-16 3 views
6

Pourquoi est-ce que push ebp est la première action de la fonction Callee d'un assemblage?Pourquoi "PUSH EBP" et "MOV EBP, ESP" dans CALLEE in Assembly?

Je comprends alors que nous utilisons mov edi, [ebp+8] pour obtenir les variables passées, mais notre esp pointe déjà vers l'adresse de retour de la fonction Caller. Nous pouvons facilement accéder aux variables passées avec mov edi, [esp+4] ou si nous avons poussé les registres de Callee, puis mov edi, [esp+16].

Alors, pourquoi avoir ce registre supplémentaire dans le CPU (le ebp) que vous devrez ensuite gérer dans les fonctions? à savoir

push ebp 
mov ebp, esp 

... 

mov esp, ebp 
pop ebp 
+3

Vous n'êtes pas obligé. Les compilateurs omettent souvent le pointeur de cadre de nos jours, si la fonction n'utilise pas de tableaux de longueur variable ou 'alloca()'. – EOF

+0

Copie possible de [Quel est exactement le pointeur de base et le pointeur de la pile? À quoi pointent-ils?] (Http://stackoverflow.com/questions/1395591/what-is-exactly-the-base-pointer-and-stack-pointer-to-what-do-they-point) –

+0

Pourquoi As-tu mis "CALLEE" en toutes-majuscules dans le titre? Vous vous demandez pourquoi l'appelant ne fait pas des cadres de pile dans le cadre de la convention d'appel? Cela ne semble pas être le cas, basé sur le texte autre que le titre. –

Répondre

4

Il met en place un nouveau stack frame au sein de l'appelé, tout en conservant le cadre de pile de l'appelant. Un cadre de pile permet un accès cohérent aux paramètres passés et aux variables locales en utilisant des décalages fixes par rapport à EBP n'importe où dans la fonction, tandis que ESP est libre de continuer à être modifié au besoin pendant que la fonction est en cours d'exécution. ESP est une cible en mouvement, donc l'accès aux paramètres et aux variables en utilisant des décalages dynamiques par rapport à ESP peut être difficile, voire impossible, selon la façon dont la fonction utilise la pile. La création d'un cadre de pile est généralement plus sûre, au prix d'utiliser quelques octets d'espace de pile pour conserver le pointeur sur le cadre de pile de l'appelant.

+0

Le coût du maintien d'un pointeur de trame n'est pas dans le seul 'push [r/e] bp', il abandonne l'utilisation gratuite d'un registre sauvé par l'appelant sur un registre affamé (ou * very * bit) l'architecture. – EOF

+0

Avoir un décalage dynamique aux variables peut être déroutant pour les humains, mais est-ce vraiment nécessaire pour un compilateur? Est-ce que les frais généraux en valent vraiment la peine? – Grigio

+0

@EOF '[R/E] BP' est réservé spécifiquement pour être utilisé comme pointeur de cadre de pile. Ce n'est pas un registre générique, comme '[R/E] AX', par exemple. –