Qu'est-ce que cela signifie pour un processeur de prendre en charge une pile?


11

Comment un processeur ne peut-il pas prendre en charge une pile? Aucune architecture qui utilise des sous-programmes (je suis sûr que ce sont toutes des architectures) n'a-t-elle pas besoin de pousser l'adresse de retour sur la pile pour qu'elle puisse retourner d'où elle a appelé le sous-programme? La pile signifie simplement une section de mémoire avec un pointeur qui croît dans une certaine direction et agit comme une structure de données de pile non? Je ne comprends tout simplement pas comment une architecture ne peut pas prendre en charge une pile.

Dans quelle mesure le stockage automatique de la mémoire (variables automatiques vs variables statiques) est-il déterminé par le compilateur vs l'architecture matérielle?

Réponses:


8

Il existe de nombreux microcontrôleurs de bas niveau qui ont des piles matérielles pour les appels / retours de sous-programmes et la gestion des interruptions, mais rendent difficile, voire impossible, de stocker des données (variables) là-bas, et la mise en œuvre d'une pile de données purement logicielle serait terriblement inefficace. Le 8051 est un exemple classique, et les PIC bas de gamme (PIC12 / PIC16) en sont un autre. Sur ces machines, la pile de données est émulée en attribuant des emplacements de stockage statiques aux variables automatiques, la quantité de réutilisation de ces emplacements dépendant de la sophistication du compilateur.

Notez que si l'émulation de pile est effectuée de cette façon, cela signifie que la récursivité - une fonction qui s'appelle elle-même, directement ou indirectement - ne fonctionne pas, car chaque instance de la fonction réutilise les mêmes emplacements statiques pour ses variables soi-disant "privées". Certains compilateurs autorisent l'utilisation limitée de la récursivité (généralement implémentée au moyen d'une #pragmasorte), ce qui entraînera la création d'une véritable pile de données, peu importe à quel point elle ralentit les choses.

En passant, il y a eu des architectures CPU qui n'avaient pas du tout de pile matérielle, pas même pour la gestion des sous-programmes / interruptions, y compris le DEC PDP-8 et IBM System / 360. Sur ces machines, le PC (adresse de retour) et le registre d'état (pour les interruptions) ont été enregistrés dans des registres ou des emplacements de mémoire, mais dans tous les cas auxquels je pense, la machine avait également des modes d'adresse suffisamment flexibles qui facilitaient la création d'une pile avec un logiciel.


1
Certains ordinateurs antérieurs écrivaient une instruction de saut dans le code pour provoquer un retour - n'ayant pas de sauts indirects - rendant les fonctions réentrantes impraticables (en théorie, on pourrait se ramifier sur un saut mais cela ajoute de la complexité, dans certains cas en particulier lorsque les adresses de données sont complètement codées dans les instructions).
Paul A. Clayton

4

«supporter une pile» signifie

  1. ayant un registre de pointeur de pile explicite, et
  2. ayant des instructions de code machine primitif pour manipuler / utiliser le registre de pointeur de pile (comme reti, qui change le compteur de programme en fonction du pointeur de pile afin de revenir d'un appel de fonction).

Vous pouvez émuler cela sans prise en charge matérielle via l'émulation, qui est du code généré par le compilateur qui fait le même genre de choses dans la RAM en utilisant des variables. Il est rare / rare de ne pas prendre en charge directement la pile dans une architecture informatique moderne.

La sémantique des variables dans les langages de programmation n'a presque rien à voir avec l'architecture matérielle cible, pour tout langage supérieur à l'assemblage simple. Le travail du compilateur est de générer un code machine conforme au contrat sémantique du langage de programmation.


1
La plupart des ISC RISC (par exemple, MIPS [sauf MIPS16 et microMIPS], Alpha, SPARC, PA-RISC, Power, SuperH) n'ont pas de registre de pointeur de pile explicite, le définissant à la place dans l'ABI. ARM est une exception (en partie parce qu'il fait de l'ombre au SP pour plusieurs modes de fonctionnement) tout comme le MIP16 et microMIPS (pour la densité de code).
Paul A. Clayton

2

Certaines architectures (par exemple PIC) ont une pile matérielle dont la capacité est limitée (ne peut être utilisée que pour les adresses de retour, pas pour les variables). Certaines architectures extrêmement petites n'ont pas d'instruction de stockage et d'incrémentation ou PUSH, il est donc plus fastidieux de faire une pile.

Les variables «auto» en C doivent toujours être compilées en quelque chose avec un comportement d'initialisation «auto» et «statique» avec un comportement statique; sur certaines architectures, vous n'êtes pas autorisé à faire de récursivité, auquel cas le compilateur peut allouer statiquement toutes les variables.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.