web-dev-qa-db-fra.com

À quoi sert un pointeur de pile dans les microprocesseurs?

Je me prépare pour un examen sur microprocesseur. Si l'utilisation d'un compteur de programme doit contenir l'adresse de l'instruction suivante, à quoi sert le pointeur de pile?

47
KAR

Une pile est une structure de données LIFO (dernier entré, premier sorti - la dernière entrée que vous poussez sur la pile) est la première que vous récupérez lorsque vous sautez) qui est généralement utilisée pour contenir la pile frames (bits de la pile qui appartiennent à la fonction courante).

Cela comprend, mais sans s'y limiter:

  • l'adresse de retour.
  • une place pour une valeur de retour.
  • paramètres passés.
  • variables locales.

Vous poussez des éléments sur la pile et les faites sauter. Dans un microprocesseur, la pile peut être utilisée à la fois pour les données utilisateur (telles que les variables locales et les paramètres passés) et les données CPU (telles que les adresses de retour lors de l'appel) sous-programmes).

L'implémentation réelle d'une pile dépend de l'architecture du microprocesseur. Il peut augmenter ou diminuer en mémoire et peut se déplacer avant ou après les opérations Push/pop.

Les opérations qui affectent généralement la pile sont les suivantes:

  • appels et retours de sous-programmes.
  • interrompre les appels et les retours.
  • code poussant et sautant explicitement les entrées.
  • manipulation directe du registre SP.

Considérez le programme suivant dans ma langue (fictive) d'assemblage:

Addr  Opcodes   Instructions    ; Comments
----  --------  --------------  ----------
                                ; 1: pc<-0000, sp<-8000
0000  01 00 07  load r0,7       ; 2: pc<-0003, r0<-7
0003  02 00     Push r0         ; 3: pc<-0005, sp<-7ffe, (sp:7ffe)<-0007
0005  03 00 00  call 000b       ; 4: pc<-000b, sp<-7ffc, (sp:7ffc)<-0008
0008  04 00     pop r0          ; 7: pc<-000a, r0<-(sp:7ffe[0007]), sp<-8000
000a  05        halt            ; 8: pc<-000a
000b  06 01 02  load r1,[sp+2]  ; 5: pc<-000e, r1<-(sp+2:7ffe[0007])
000e  07        ret             ; 6: pc<-(sp:7ffc[0008]), sp<-7ffe

Suivons maintenant l'exécution, en décrivant les étapes indiquées dans les commentaires ci-dessus:

  1. Il s'agit de la condition de départ où le compteur de programme est zéro et le pointeur de pile est 8000 (tous ces nombres sont hexadécimaux).
  2. Cela charge simplement le registre r0 avec la valeur immédiate 7 et passe à l'étape suivante (je suppose que vous comprenez que le comportement par défaut sera de passer à l'étape suivante, sauf indication contraire).
  3. Cela pousse r0 sur la pile en réduisant le pointeur de pile de deux puis en stockant la valeur du registre à cet emplacement.
  4. Cela appelle un sous-programme. Ce que aurait été le compteur de programme est poussé sur la pile de la même manière que r0 à l'étape précédente, puis le compteur de programme est défini sur sa nouvelle valeur. Ce n'est pas différent d'un Push au niveau de l'utilisateur autre que le fait qu'il est fait plus en tant que chose au niveau du système.
  5. Cela charge r1 à partir d'un emplacement mémoire calculé à partir du pointeur de pile - il montre un moyen de passer des paramètres aux fonctions.
  6. L'instruction return extrait la valeur à partir de laquelle pointe le pointeur de pile et la charge dans le compteur de programme, en ajustant le pointeur de pile vers le haut en même temps. C'est comme un pop au niveau du système (voir l'étape suivante).
  7. Popping r0 hors de la pile implique d'extraire la valeur d'où le pointeur de la pile pointe, puis d'ajuster ce pointeur de pile vers le haut.
  8. L'instruction Halt laisse simplement le compteur de programme où il se trouve, une sorte de boucle infinie.

Espérons que d'après cette description, cela deviendra clair. En résumé, une pile est utile pour stocker l'état d'une manière LIFO et c'est généralement idéal pour la façon dont la plupart des microprocesseurs effectuent des appels de sous-routine.

Sauf si vous êtes un SPARC bien sûr, auquel cas vous utilisez un tampon circulaire pour votre pile :-)

Mise à jour: Juste pour clarifier les étapes prises lors de la poussée et du popping des valeurs dans l'exemple ci-dessus (que ce soit explicitement ou par appel/retour), voir les exemples suivants:

LOAD R0,7
Push R0
                     Adjust sp       Store val
sp-> +--------+      +--------+      +--------+
     |  xxxx  |  sp->|  xxxx  |  sp->|  0007  |
     |        |      |        |      |        |
     |        |      |        |      |        |
     |        |      |        |      |        |
     +--------+      +--------+      +--------+

POP R0
                     Get value       Adjust sp
     +--------+      +--------+  sp->+--------+
sp-> |  0007  |  sp->|  0007  |      |  0007  |
     |        |      |        |      |        |
     |        |      |        |      |        |
     |        |      |        |      |        |
     +--------+      +--------+      +--------+
91
paxdiablo

Le pointeur de pile stocke l'adresse de l'entrée la plus récente qui a été insérée dans la pile.

Pour pousser une valeur sur la pile, le pointeur de pile est incrémenté pour pointer vers la prochaine adresse de mémoire physique et la nouvelle valeur est copiée vers cette adresse en mémoire.

Pour extraire une valeur de la pile, la valeur est copiée à partir de l'adresse du pointeur de pile et le pointeur de pile est décrémenté, en le pointant vers l'élément disponible suivant dans la pile.

L'utilisation la plus courante d'une pile matérielle consiste à stocker l'adresse de retour d'un appel de sous-programme. Lorsque l'exécution du sous-programme est terminée, l'adresse de retour est extraite du haut de la pile et placée dans le registre du compteur de programmes, ce qui oblige le processeur à reprendre l'exécution à l'instruction suivante après l'appel au sous-programme.

http://en.wikipedia.org/wiki/Stack_%28data_structure%29#Hardware_stacks

11
Robert Harvey

Vous avez plus de préparation [pour l'examen] à faire ;-)

Le Stack Pointer est un registre qui contient l'adresse du prochain emplacement disponible sur la pile.

La pile est une zone en mémoire réservée pour stocker une pile, c'est-à-dire un type de conteneur LIFO (Last In First Out), où nous stockons les variables locales et l'adresse de retour, permettant gestion simple de l'imbrication des appels de fonction dans un programme type.

Voir ceci article Wikipedia pour une explication de base de la gestion de la pile.

6
mjv

Pour 8085: le pointeur de pile est un registre spécial de 16 bits dans le microprocesseur, qui contient l'adresse du haut de la pile.

Le registre de pointeur de pile dans un ordinateur est rendu disponible pour une utilisation générale par des programmes s'exécutant à des niveaux de privilège inférieurs à ceux des gestionnaires d'interruption. Un ensemble d'instructions dans de tels programmes, à l'exclusion des opérations de pile, stocke des données autres que le pointeur de pile, telles que des opérandes, etc., dans le registre de pointeur de pile. Lors du basculement de l'exécution vers un gestionnaire d'interruption sur une interruption, les données d'adresse de retour pour le programme en cours d'exécution sont poussées sur une pile au niveau de privilège du gestionnaire d'interruption. Ainsi, le stockage d'autres données dans le registre de pointeur de pile n'entraîne pas de corruption de pile. De plus, ces instructions peuvent stocker des données dans une partie temporaire d'un segment de pile au-delà du pointeur de pile actuel.

Lisez celui-ci pour plus d'informations.

tilisation générale d'un registre de pointeur de pile

3
rahul

La pile est une zone de mémoire pour conserver des données temporaires. La pile est utilisée par l'instruction CALL pour conserver l'adresse de retour des procédures. L'instruction de retour RET obtient cette valeur de la pile et retourne à ce décalage. La même chose se produit lorsqu'une instruction INT appelle une interruption. Il stocke dans la pile le registre des drapeaux, le segment de code et le décalage. L'instruction IRET est utilisée pour revenir d'un appel interrompu.

La pile est une mémoire LIFO (Last In First Out). Les données sont placées sur la pile avec une instruction Push et supprimées avec une instruction POP. La mémoire de pile est maintenue par deux registres: le pointeur de pile (SP) et le registre de segment de pile (SS). Lorsqu'un mot de données est poussé sur la pile, l'octet 8 bits d'ordre supérieur est placé à l'emplacement SP-1 et l'octet 8 bits bas est placé à l'emplacement SP-2. Le SP est ensuite décrémenté de 2. Le SP ajoute au registre (SS x 10H), pour former l'adresse mémoire de la pile physique. La séquence inverse se produit lorsque les données sont POPPED à partir de la pile. Lorsqu'un mot de données est POPPED à partir de la pile, l'octet 8 bits d'ordre supérieur est obtenu à l'emplacement SP-1 et l'octet 8 bits bas est obtenu à l'emplacement SP-2. SP est ensuite incrémenté de 2.

2
priyadharshini-D

Si jamais vous désirez une compréhension plus profonde, je recommande chaleureusement Patterson et Hennessy comme intro et Hennessy et Patterson comme texte intermédiaire à avancé. Ils sont chers, mais vraiment sans pareil; Je souhaite juste que l'un ou les deux soient disponibles lorsque j'ai obtenu ma maîtrise et que je suis entré sur le marché du travail en concevant des puces, des systèmes et des parties de logiciels système pour eux (mais, hélas!, C'était beaucoup trop longtemps ;-). Les pointeurs de pile sont si cruciaux (et la distinction entre un microprocesseur et tout autre type de CPU si important dans ce contexte ... ou, d'ailleurs, dans TOUT autre contexte, au cours des dernières décennies ...! -) que Je doute de quoi que ce soit, mais quelques rafraîchissements complets à partir du sol peuvent vous aider! -)

1
Alex Martelli

Le pointeur de pile contient l'adresse en haut de la pile. Une pile permet aux fonctions de se transmettre des arguments stockés sur la pile et de créer portée variables. La portée dans ce contexte signifie que la variable est extraite de la pile lorsque le cadre de la pile a disparu et/ou lorsque la fonction revient. Sans pile, vous auriez besoin d'utiliser des adresses mémoire explicites pour tout. Cela rendrait impossible (ou du moins très difficile) la conception de langages de programmation de haut niveau pour l'architecture. De plus, chaque mode CPU possède généralement son propre pointeur de pile en banque. Ainsi, lorsque des exceptions se produisent (interruptions par exemple), la routine du gestionnaire d'exceptions peut utiliser sa propre pile sans corrompre le processus utilisateur.

1
Mads Elvheim

Sur certains CPU, il existe un ensemble dédié de registres pour la pile. Lorsqu'une instruction d'appel est exécutée, un registre est chargé avec le compteur de programme en même temps qu'un deuxième registre est chargé avec le contenu du premier, un troisième registre est chargé avec le second, et un quatrième avec le troisième, etc. Lorsqu'une instruction de retour est exécutée, le compteur de programme est verrouillé avec le contenu du premier registre de pile et en même temps que ce registre est verrouillé du second; ce deuxième registre est chargé à partir d'un troisième, etc. Notez que ces piles matérielles ont tendance à être plutôt petites (de nombreux micros de la série PIC, par exemple, ont une pile à deux niveaux).

Bien qu'une pile matérielle présente certains avantages (push et pop n'ajoutent pas de temps à un appel/retour, par exemple), avoir des registres qui peuvent être chargés avec deux sources ajoute du coût. Si la pile devient très grande, il sera moins coûteux de remplacer les registres push-pull par une mémoire adressable. Même si une petite mémoire dédiée est utilisée pour cela, il est moins cher d'avoir 32 registres adressables et un registre de pointeur 5 bits avec logique d'incrémentation/décrémentation, que d'avoir 32 registres chacun avec deux entrées. Si une application peut avoir besoin de plus de pile que ce qui pourrait facilement être installé sur le CPU, il est possible d'utiliser un pointeur de pile avec une logique pour stocker/récupérer les données de pile de la RAM principale.

0
supercat

Un pointeur de pile est un petit registre qui stocke l'adresse du haut de la pile. Il est utilisé dans le but de pointer l'adresse du haut de la pile.

0
rashedcs