Je ne connais pas encore très bien la terminologie de l'architecture informatique, alors soyez indulgent avec moi. Je semble comprendre que les architectures de von Neumann sont plus robustes ("machines de Turing universelles") que les architectures de Harvard, mais je ne connais pas encore trop les détails.
Après avoir passé ces dernières nuits à chercher dans Call Stack , je suis toujours confus . J'ai également vu quelques articles ici et là (juste en train de scanner les résumés pour le moment), tels que Programmation sans pile d'appels, et d'autres, ce qui me fait me demander s'il existe des systèmes/architectures pour définir une machine virtuelle sans pile d'appel . Je ne sais pas vraiment à quoi cela ressemblerait, mais il y a peut-être des choses à vérifier. Je ne parle pas de machines simples , comme celles d'avant les années 1960 qui n'avaient pas de récursivité et donc n'avaient pas besoin de piles d'appels je suppose . Je parle d'architectures informatiques entièrement robustes/complètes qui utilisent autre chose qu'une pile d'appels.
... ce qui me fait me demander s'il existe des systèmes/architectures pour définir une machine virtuelle sans pile d'appels
Continuation Passing Style active optimisation des appels de queue pour toutes les invocations de fonctions - ainsi, aucune pile n'est nécessaire; cependant, la mémoire de tas est très probablement utilisée pour contenir les fermetures capturant les références aux variables locales.
CPS est utilisé comme forme intermédiaire (par exemple dans un jeu d'instructions virtuel) dans certains compilateurs pour représenter un flux de contrôle explicite, en particulier ce qui se passe dans les exceptions et la gestion des exceptions.
La pile est une structure de données très efficace: le haut de la pile est presque certainement dans le cache de données, et l'allocation et la désallocation sont super rapides (c'est-à-dire une instruction). La pile est une partie nécessaire pour les programmes C, il est donc peu probable qu'un ordinateur moderne soit fabriqué sans prise en charge explicite d'une pile.
Cependant, pour être clair, MIPS et RISC V n'ont pas de pointeurs de pile dédiés au matériel séparés ni d'instructions Push and Pop - le logiciel utilise simplement l'un des nombreux registres à usage général de cette façon.
Je ne pense pas que la robustesse soit un problème ici. La fonctionnalité est, au sens le plus littéral.
Oubliez les détails d'implémentation pendant un moment et réfléchissez à ce qu'est vraiment une pile d'appels. Il vous permet d'appeler des sous-programmes (fonctions) et de revenir d'eux, en continuant là où vous vous étiez arrêté. Autrement dit, il offre la possibilité de diviser un problème en parties plus petites, pour créer des blocs de construction fonctionnels.
C'est une caractéristique si fondamentale dans une machine de résolution de problèmes à usage général qu'il serait difficile d'imaginer sans elle. Ce serait inutile car il n'y aurait aucun moyen de créer quelque chose de complexe.
Ce que vous appelez "robuste" est une question de préférence.
Les piles sont utiles, mais il n'est pas nécessaire que l'architecture les définisse directement.
Un programme peut toujours créer ses propres piles s'il le souhaite.
Avoir un support matériel pour quelque chose le rend plus rapide, mais moins flexible.
Les architectures avec des piles d'appels rendent les appels de fonction rapides, mais pas très rapides car il y a généralement du travail à faire avec les transferts d'arguments.
D'un autre côté, vous êtes enfermé dans un monde Last-In-First-Out pour les appels de fonction et les retours. Si vous voulez utiliser coroutines, la pile ne vous aide plus.
Le matériel dont nous disposons affecte les programmes que nous écrivons. Et les programmes que nous écrivons affectent le matériel que nous voulons. En fin de compte, ce que nous avons semble "nécessaire", même s'il ne s'agit que d'un choix parmi tant d'autres.
Vous n'avez pas besoin d'appeler piles nécessairement à n'importe quel niveau, que ce soit le niveau du langage de programmation ou le niveau matériel.
Du point de vue de l'architecture informatique, il n'est pas nécessaire de prendre en charge le matériel pour une pile bénie (par exemple, un registre de pointeur de pile spécial, des instructions pour charger et stocker des valeurs relatives à cette pile, etc.) afin d'implémenter un langage semi-arbitraire imbrication d'appel de fonction comme C ou Scheme. Vous pouvez implémenter le vôtre avec un registre, un adressage à décalage de registre et incrémenter et décrémenter manuellement le registre que vous avez désigné comme "pointeur de pile". Le support de pile d'appels dans le jeu d'instructions est là pour la compacité du code machine.
Du point de vue du langage de programmation, la pile n'est qu'un détail d'implémentation. La norme C ne l'appelle pas une pile, elle fait référence aux variables de pile comme "automatiques" (car leur stockage est automatiquement désalloué lorsque vous quittez la portée dans laquelle elles ont été définies). La convention d'appel standard dans les systèmes d'exploitation populaires consiste à utiliser la pile de sorte que les utilisateurs supposent que cela doit être fait.
Les langues avec des continuations de première classe ne fonctionnent pas comme s'il y avait une pile, conceptuellement. Les quatrième implémentations utilisent généralement deux piles. Le code CPSd n'utilise conceptuellement aucune pile. Il existe de nombreuses façons de le faire, des "piles" de branchement allouées au tas utilisées pour implémenter les continuations et les coroutines jusqu'au bog standard C.