Structure générale du cadre de pile
CLa langue appelle la procédure(Fonctions)En utilisant le principe de gestion de la mémoire du dernier entré premier sorti fourni par la structure de données de la pile.
QuandQ Au moment de l'exécution, p Et tout ce qui remonte àP Processus dans la chaîne d'appels pour,Tout est suspendu temporairement.
Quandx86-64 La procédure nécessite plus d'espace de stockage que le registre ne peut stocker pendant une heure,Il y aura de l'espace sur la pile,Cette partie s'appelle le cadre de pile du processus(stack fram).
La figure suivante montre la structure générale de la pile d'exécution,Y compris la Division en cadres de pile.Le cadre du processus en cours d'exécution est toujours en haut de la pile.
Nous pouvons voirPProcédure d'appelQHeure,Adjacent au cadre de pile des deux processus,EtPÀQLes adresses sont réduites à tour de rôle(En bas.).

Il n'y a pas de détails ici sur la construction générale du cadre de pile,Pour plus de détails, voirCSAPPMoyenne3.7.1Chapitre.
Exécution du cadre de pile
Avec simplicitémainAppel de fonctionaddExpliquer la fonction par exemple.
Environnement opérationnel:Linux Ubuntu 1404LTS i386 +gcc
#include<stdio.h> int add(int a,int b) { return a+b; } int main() { int res=add(1,2); return 0; }
gccCompilez - le
gcc -S hello.c hello.s
UtiliservscodeOuvre.hello.sAssembler des fichiers. Supprimer les informations annotées .
add: pushl %ebp //Oui.ebpAppuyez sur la pile【Hypothèsesebp=addr2】,EnregistrermainCadre de pile pour la fonction(Au fond de la pile) movl %esp, %ebp // Assigner la valeur supérieure actuelle de la pile à %ebp,En ce moment%ebp C'est une nouvelle fonction (add)Au fond de la pile movl 12(%ebp), %eax //Oui.12+M(%ebp) La valeur en mémoire passe à %eaxRegistres, La valeur à cette mémoire est en fait main Sur le cadre de pile de la fonction movl 8(%ebp), %edx //Comme ci - dessus addl %edx, %eax // Enregistrer les valeurs des deux registres ensemble dans %eaxSur le registre(Stocker la valeur de retour) popl %ebp //Éjection de la pile,Va maintenantaddr2 Valeur enregistrée dans le registre %ebp, Le pointeur du bas de la pile pointe vers addr2C'est l'originalmainBase de pile de la fonction ret //Prends ça.main La valeur de l'adresse de retour de la fonction est assignée à rip main: pushl %ebp //Oui.main De la fonction précédente ebpAppuyez sur la pile movl %esp, %ebp // Va à la fonction précédente esp Le pointeur supérieur de la pile est stocké dans %ebpRegistres,En ce moment%esp,%ebpPointez au même endroit,Mais...%ebp Le sens ici est le nouveau cadre de pile (mainBase de pile de la fonction) subl $24, %esp //Pourmain La fonction ouvre l'espace de pile 24byte movl $2, 4(%esp) //Nombre immédiat2DépôtM(%esp)+4Mémoire cdeclComment( Les arguments sont empilés de droite à gauche ) movl $1, (%esp) //Nombre immédiat1DépôtM(%esp)Mémoire call add //AppelezcallHeure, Effectuer deux actions :Oui.main L'adresse de retour de la fonction est pressée sur la pile ;Oui.addAdresse d'entrée de la fonctionEntryPointAssigner une valeur àrip, Exécution immédiate addFonctions movl %eax, -4(%ebp) //Oui.%eax La valeur du registre est déplacée en mémoire M(%ebp) movl $0, %eax //eaxAssigner comme0 leave ret
L'illustration est la suivante :









