Un cadre de pile est un cadre de données qui est poussé sur la pile. Dans le cas d'une pile d'appels, une trame de pile représenterait un appel de fonction et ses données d'argument.
Si je me souviens bien, l'adresse de retour de la fonction est d'abord poussée sur la pile, puis les arguments et l'espace pour les variables locales. Ensemble, ils font le «cadre», bien que cela dépende probablement de l'architecture. Le processeur sait combien d'octets se trouvent dans chaque trame et déplace le pointeur de pile en conséquence lorsque les trames sont poussées et sautées hors de la pile.
ÉDITER:
Il existe une grande différence entre les piles d'appels de niveau supérieur et la pile d'appels du processeur.
Lorsque nous parlons de la pile d'appels d'un processeur, nous parlons de travailler avec des adresses et des valeurs au niveau octet / mot dans l'assembly ou le code machine. Il existe des «piles d'appels» lorsque l'on parle de langages de niveau supérieur, mais ce sont des outils de débogage / d'exécution gérés par l'environnement d'exécution afin que vous puissiez enregistrer ce qui s'est mal passé avec votre programme (à un niveau élevé). À ce niveau, des choses comme les numéros de ligne et les noms de méthode et de classe sont souvent connues. Au moment où le processeur obtient le code, il n'a absolument aucune idée de ces choses.
Si vous comprenez très bien la pile, vous comprendrez comment fonctionne la mémoire dans le programme et si vous comprenez comment la mémoire fonctionne dans le programme, vous comprendrez comment le magasin de fonctions dans le programme et si vous comprenez comment le magasin de fonctions dans le programme, vous comprendrez comment fonctionne la fonction récursive et si vous comprenez comment fonctionne la fonction récursive, vous comprendrez comment fonctionne le compilateur et si vous comprenez comment fonctionne le compilateur, votre esprit fonctionnera comme compilateur et vous déboguerez n'importe quel programme très facilement
Permettez-moi d'expliquer comment fonctionne la pile:
Vous devez d'abord savoir comment les fonctions sont représentées dans la pile:
Le tas stocke les valeurs allouées dynamiquement.
La pile stocke les valeurs d'allocation et de suppression automatiques.
Comprenons par exemple:
Comprenez maintenant certaines parties de ce programme:
Voyons maintenant ce qu'est la pile et quelles sont les pièces de la pile:
N'oubliez pas une chose: si la condition de retour d'une fonction est satisfaite, qu'elle ait chargé les variables locales ou non, elle reviendra immédiatement de la pile avec son cadre de pile. Cela signifie que chaque fois qu'une fonction récursive obtient la condition de base satisfaite et que nous mettons un retour après la condition de base, la condition de base n'attendra pas pour charger les variables locales qui se trouvent dans la partie "else" du programme. Il renverra immédiatement l'image actuelle de la pile à la suite de laquelle l'image suivante est maintenant dans l'enregistrement d'activation.
Voir cela en pratique:
Alors maintenant, chaque fois qu'une fonction rencontre l'instruction return, elle supprime le cadre actuel de la pile.
Lors du retour de la pile, les valeurs seront retournées en sens inverse de l'ordre d'origine dans lequel elles ont été allouées dans la pile.
la source
hello()
a appelé récursivementhello()
qui a ensuite (encore) récursivement appeléhello()
, et le cadre global est la fonction d'origine qui a appelé le premierhello()
?Un résumé rapide. Peut-être que quelqu'un a une meilleure explication.
Une pile d'appels est composée de 1 ou plusieurs trames de pile. Chaque trame de pile correspond à un appel à une fonction ou une procédure qui ne s'est pas encore terminée par un retour.
Pour utiliser un cadre de pile, un thread conserve deux pointeurs, l'un s'appelle le pointeur de pile (SP) et l'autre s'appelle le pointeur de cadre (FP). SP pointe toujours vers le "haut" de la pile, et FP pointe toujours vers le "haut" du cadre. De plus, le thread maintient également un compteur de programmes (PC) qui pointe vers la prochaine instruction à exécuter.
Les éléments suivants sont stockés sur la pile: variables locales et temporelles, paramètres réels de l'instruction courante (procédure, fonction, etc.)
Il existe différentes conventions d'appel concernant le nettoyage de la pile.
la source
"Une pile d'appels est composée de trames de pile ..." - Wikipedia
Un cadre de pile est une chose que vous mettez sur la pile. Ce sont des structures de données qui contiennent des informations sur les sous-programmes à appeler.
la source
Les programmeurs peuvent avoir des questions sur les trames de pile non pas dans un sens large (qu'il s'agit d'une entité unique dans la pile qui sert un seul appel de fonction et conserve l'adresse de retour, les arguments et les variables locales) mais au sens étroit - lorsque le terme
stack frames
est mentionné dans contexte des options du compilateur.Que l'auteur de la question le veuille ou non, mais le concept d'un cadre de pile du point de vue des options du compilateur est une question très importante, non couverte par les autres réponses ici.
Par exemple, le compilateur C / C ++ Microsoft Visual Studio 2015 a l'option suivante liée à
stack frames
:GCC dispose des éléments suivants:
Le compilateur Intel C ++ possède les éléments suivants:
qui a l'alias suivant:
Delphi a l'option de ligne de commande suivante:
Dans ce sens spécifique, du point de vue du compilateur, un cadre de pile n'est que le code d'entrée et de sortie de la routine , qui pousse une ancre vers la pile - qui peut également être utilisée pour le débogage et pour la gestion des exceptions. Les outils de débogage peuvent analyser les données de la pile et utiliser ces ancres pour le retour en arrière, tout en les localisant
call sites
dans la pile, c'est-à-dire pour afficher les noms des fonctions dans l'ordre où elles ont été appelées hiérarchiquement. Pour l'architecture Intel, c'estpush ebp; mov ebp, esp
soitenter
pour l'entrée etmov esp, ebp; pop ebp
soitleave
pour la sortie.C'est pourquoi il est très important de comprendre pour un programmeur ce qu'est un cadre de pile en ce qui concerne les options du compilateur - car le compilateur peut contrôler s'il faut générer ce code ou non.
Dans certains cas, le cadre de pile (code d'entrée et de sortie pour la routine) peut être omis par le compilateur, et les variables seront directement accessibles via le pointeur de pile (SP / ESP / RSP) plutôt que le pointeur de base pratique (BP / ESP / RSP). Conditions d'omission du cadre de pile, par exemple:
L'omission de trames de pile (code d'entrée et de sortie pour la routine) peut rendre le code plus petit et plus rapide, mais cela peut également affecter négativement la capacité des débogueurs à retracer les données de la pile et à les afficher au programmeur. Ce sont les options du compilateur qui déterminent dans quelles conditions une fonction doit avoir le code d'entrée et de sortie, par exemple: (a) toujours, (b) jamais, (c) si nécessaire (en spécifiant les conditions).
la source
La trame de pile est l'information emballée liée à un appel de fonction. Ces informations incluent généralement des arguments passés à la fonction, des variables locales et où retourner à la fin. L'enregistrement d'activation est un autre nom pour un cadre de pile. La disposition du cadre de pile est déterminée dans l'ABI par le fabricant et chaque compilateur prenant en charge l'ISA doit être conforme à cette norme, mais le schéma de disposition peut dépendre du compilateur. Généralement, la taille de trame de pile n'est pas limitée mais il existe un concept appelé "zone rouge / protégée" pour permettre aux appels système ... etc de s'exécuter sans interférer avec une trame de pile.
Il y a toujours un SP mais sur certains ABI (ARM et PowerPC par exemple) FP est optionnel. Les arguments qui devaient être placés sur la pile peuvent être compensés à l'aide du SP uniquement. La génération ou non d'un cadre de pile pour un appel de fonction dépend du type et du nombre d'arguments, des variables locales et de la manière dont les variables locales sont généralement accessibles. Sur la plupart des ISA, tout d'abord, des registres sont utilisés et s'il y a plus d'arguments que de registres dédiés à passer des arguments, ils sont placés sur la pile (par exemple, x86 ABI a 6 registres pour passer des arguments entiers). Par conséquent, parfois, certaines fonctions n'ont pas besoin d'un cadre de pile pour être placées sur la pile, juste l'adresse de retour est poussée sur la pile.
la source