¿Cómo puede una CPU no soportar una pila? ¿Ninguna arquitectura que usa subrutinas (estoy bastante seguro de que son todas las arquitecturas) tiene que insertar la dirección de retorno en la pila para que pueda regresar a donde llamó la subrutina? La pila solo significa una sección de memoria con un puntero que crece en cierta dirección y actúa como una estructura de datos de la pila, ¿no? Simplemente no entiendo cómo una arquitectura no podría soportar una pila.
¿En qué medida el almacenamiento automático de memoria (variables automáticas frente a variables estáticas) lo determina el compilador frente a la arquitectura de hardware?
Hay muchos microcontroladores de bajo nivel que tienen pilas de hardware para llamadas / devoluciones de subrutina y manejo de interrupciones, pero hacen que sea difícil, si no imposible, almacenar datos (variables) allí, e implementar una pila de datos puramente de software sería terriblemente ineficiente. El 8051 es un ejemplo clásico, y los PIC de gama baja (PIC12 / PIC16) son otro. En estas máquinas, la pila de datos se emula asignando ubicaciones de almacenamiento estático para variables automáticas, y la cantidad de reutilización de estas ubicaciones depende de la sofisticación del compilador.
Tenga en cuenta que si la emulación de pila se realiza de esta manera, significa que la recursión, una función que se llama a sí misma, ya sea directa o indirectamente, no funciona, ya que cada instancia de la función reutiliza las mismas ubicaciones estáticas para sus variables supuestamente "privadas". Algunos compiladores permiten el uso limitado de la recursividad (generalmente implementada por medio de #pragmaalgún tipo), lo que hará que cree una verdadera pila de datos sin importar cuánto desacelere las cosas.
Por otro lado, ha habido arquitecturas de CPU que no tenían una pila de hardware, ni siquiera para el manejo de subrutinas / interrupciones, incluidos DEC PDP-8 e IBM System / 360. En estas máquinas, la PC (dirección de retorno) y el registro de estado (para interrupciones) se guardaron en registros o ubicaciones de memoria, pero en cada caso que se me ocurre, la máquina también tenía modos de dirección suficientemente flexibles que facilitaban la creación de una pila con software
Algunas computadoras anteriores escribirían una instrucción de salto en el código para causar un retorno, sin tener saltos indirectos, haciendo que las funciones reentrantes no sean prácticas (teóricamente, uno podría ramificarse sobre un salto, pero eso agrega complejidad, en algunos casos especialmente cuando las direcciones de datos están completamente codificadas en instrucciones).
Paul A. Clayton
4
"apoyar una pila" significa
tener un registro explícito de puntero de pila, y
tener instrucciones de código de máquina primitivas para manipular / usar el registro del puntero de la pila (como reti, que cambia el contador del programa basado en el puntero de la pila para regresar de una llamada de función).
Puede emular esto sin soporte de hardware a través de la emulación, que es un código generado por el compilador que hace el mismo tipo de cosas en la RAM usando variables. Es raro / poco común no tener soporte directo para la pila en cualquier arquitectura de computadora moderna.
La semántica de las variables en los lenguajes de programación no tiene casi nada que ver con la arquitectura de hardware de destino, para cualquier lenguaje superior al ensamblaje directo. El trabajo de los compiladores es generar código de máquina que cumpla con el contrato semántico del lenguaje de programación.
La mayoría de los ISA RISC (p. Ej., MIPS [excluyendo MIPS16 y microMIPS], Alpha, SPARC, PA-RISC, Power, SuperH) no tienen un registro de puntero de pila explícito, definiéndolo en el ABI. ARM es una excepción (en parte porque sombrea el SP para varios modos de funcionamiento) como lo son MIP16 y microMIPS (para densidad de código).
Paul A. Clayton
2
Algunas arquitecturas (por ejemplo, PIC) tienen una pila de hardware que tiene una capacidad limitada (solo se puede usar para direcciones de retorno, no variables). Algunas arquitecturas extremadamente pequeñas no tienen una instrucción store-and-increment o PUSH, por lo que es más complicado hacer una pila.
Las variables 'auto' en C siempre deben compilarse en algo con comportamiento de inicialización 'auto' y 'estático' con comportamiento estático; en algunas arquitecturas no se le permite hacer recursividad, en cuyo caso el compilador puede asignar estáticamente todas las variables.
"apoyar una pila" significa
Puede emular esto sin soporte de hardware a través de la emulación, que es un código generado por el compilador que hace el mismo tipo de cosas en la RAM usando variables. Es raro / poco común no tener soporte directo para la pila en cualquier arquitectura de computadora moderna.
La semántica de las variables en los lenguajes de programación no tiene casi nada que ver con la arquitectura de hardware de destino, para cualquier lenguaje superior al ensamblaje directo. El trabajo de los compiladores es generar código de máquina que cumpla con el contrato semántico del lenguaje de programación.
fuente
Algunas arquitecturas (por ejemplo, PIC) tienen una pila de hardware que tiene una capacidad limitada (solo se puede usar para direcciones de retorno, no variables). Algunas arquitecturas extremadamente pequeñas no tienen una instrucción store-and-increment o PUSH, por lo que es más complicado hacer una pila.
Las variables 'auto' en C siempre deben compilarse en algo con comportamiento de inicialización 'auto' y 'estático' con comportamiento estático; en algunas arquitecturas no se le permite hacer recursividad, en cuyo caso el compilador puede asignar estáticamente todas las variables.
fuente