una sistemas sirve registros registro que programacion programa pointer pila para operativos instrucciones informatica contador apuntador stack microprocessors

stack - sistemas - ¿Para qué sirve un puntero de pila en microprocesadores?



sp apuntador de pila (9)

El puntero de pila almacena la dirección de la entrada más reciente que se insertó en la pila.

Para insertar un valor en la pila, el puntero de la pila se incrementa para apuntar a la siguiente dirección de memoria física, y el nuevo valor se copia a esa dirección en la memoria.

Para extraer un valor de la pila, el valor se copia de la dirección del puntero de la pila, y el puntero de la pila se decrementa, apuntándolo al siguiente elemento disponible en la pila.

El uso más típico de una pila de hardware es almacenar la dirección de retorno de una llamada de subrutina. Cuando la subrutina termina de ejecutarse, la dirección de retorno aparece en la parte superior de la pila y se coloca en el registro del contador de programas, lo que hace que el procesador reanude la ejecución en la siguiente instrucción que sigue a la llamada a la subrutina.

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

Me estoy preparando para un examen de microprocesador. Si el uso de un contador de programa es para mantener la dirección de la siguiente instrucción, ¿para qué sirve el puntero de pila?


El puntero de pila mantiene la dirección en la parte superior de la pila. Una pila permite que las funciones pasen los argumentos almacenados en la pila entre sí y que creen variables de ámbito . El alcance en este contexto significa que la variable se saca de la pila cuando el marco de pila se ha ido, y / o cuando la función regresa. Sin una pila, necesitarías usar direcciones de memoria explícitas para todo. Eso haría imposible (o al menos seriamente difícil) diseñar lenguajes de programación de alto nivel para la arquitectura. Además, cada modo de CPU generalmente tiene su propio puntero de pila bancaria. Por lo tanto, cuando se producen excepciones (interrupciones, por ejemplo), la rutina del manejador de excepciones puede usar su propia pila sin corromper el proceso del usuario.


En algunas CPU, hay un conjunto dedicado de registros para la pila. Cuando se ejecuta una instrucción de llamada, un registro se carga con el contador de programa al mismo tiempo que se carga un segundo registro con el contenido del primero, un tercer registro se carga con el segundo y un cuarto con el tercero, etc. Cuando se ejecuta una instrucción de retorno, el contador del programa se enclava con los contenidos del primer registro de pila y al mismo tiempo que el registro se enclava desde el segundo; ese segundo registro se carga desde un tercero, etc. Tenga en cuenta que tales pilas de hardware tienden a ser bastante pequeñas (muchas de las micros de la serie PIC más pequeñas, por ejemplo, tienen una pila de dos niveles).

Mientras que una pila de hardware tiene algunas ventajas (presionar y soltar no agrega tiempo a una llamada / devolución, por ejemplo) tener registros que se pueden cargar con dos fuentes agrega costos. Si la pila se pone muy grande, será más económico reemplazar los registros push-pull con una memoria direccionable. Incluso si se usa una pequeña memoria dedicada para esto, es más barato tener 32 registros direccionables y un registro de puntero de 5 bits con lógica de incremento / decremento, que tener 32 registros cada uno con dos entradas. Si una aplicación puede necesitar más pila de la que cabría fácilmente en la CPU, es posible usar un puntero de pila junto con la lógica para almacenar / recuperar datos de pila de la RAM principal.


La Pila es un área de memoria para guardar datos temporales. Stack es utilizado por la instrucción CALL para mantener la dirección de retorno para los procedimientos. La instrucción return RET obtiene este valor de la pila y regresa a esa compensación. Lo mismo sucede cuando una instrucción INT llama a una interrupción. Almacena en la pila el registro de bandera, el segmento de código y el desplazamiento. La instrucción IRET se usa para regresar de la llamada de interrupción.

La pila es una memoria de último en entrar primero (LIFO). Los datos se colocan en la pila con una instrucción PUSH y se eliminan con una instrucción POP. La memoria de pila se mantiene mediante dos registros: el puntero de pila (SP) y el registro de segmento de pila (SS). Cuando una palabra de datos se EMPUJA en la pila, el byte de 8 bits de orden superior se coloca en la ubicación SP-1 y el byte de 8 bits bajo se coloca en la ubicación SP-2. Luego, el SP se disminuye en 2. El SP se suma al registro (SS x 10H), para formar la dirección física de la memoria de la pila. La secuencia inversa ocurre cuando los datos son AMPLIADOS desde la Pila. Cuando una palabra de datos es AMPLIADA desde la pila, se obtiene el Byte de 8 bits de orden superior en la ubicación SP-1 y el Byte de 8 bits bajo en la ubicación SP-2. El SP luego se incrementa en 2.


Para 8085: Stack Pointer es un registro de 16 bits de propósito especial en el Microprocesador, que contiene la dirección de la parte superior de la pila.

El registro del puntero de la pila en una computadora está disponible para uso general por los programas que se ejecutan en niveles de privilegios más bajos que los controladores de interrupción. Un conjunto de instrucciones en tales programas, excluyendo las operaciones de pila, almacena datos que no sean el puntero de pila, tales como operandos, y similares, en el registro de puntero de pila. Cuando se cambia la ejecución a un controlador de interrupción en una interrupción, los datos de la dirección de retorno para el programa que se está ejecutando se envían a una pila en el nivel de privilegio del manejador de interrupciones. Por lo tanto, almacenar otros datos en el registro del puntero de la pila no da como resultado la corrupción de la pila. Además, estas instrucciones pueden almacenar datos en una porción de cero de un segmento de pila más allá del puntero de pila actual.

Lea este para más información.

Uso de propósito general de un registro de puntero de pila


Si alguna vez desea una comprensión más profunda, recomiendo encarecidamente Patterson y Hennessy como una introducción, y Hennessy y Patterson como un texto intermedio a avanzado. Son caros, pero verdaderamente no pareil; Solo desearía que alguno o ambos estuvieran disponibles cuando obtuve mi título de maestría y me incorporé a la fuerza de trabajo diseñando chips, sistemas y partes de software de sistema para ellos (pero, ¡ay !, eso fue hace mucho tiempo ;-). Los punteros de pila son tan cruciales (y la distinción entre un microprocesador y cualquier otro tipo de CPU es tan significativa en este contexto ... o, para el caso, en CUALQUIER otro contexto, en las últimas décadas ...! -) ¡Lo dudo todo, pero un par de refrescantes minuciosos pueden ayudar!


Tienes más preparación [para el examen] para hacer ;-)

El Stack Pointer es un registro que contiene la dirección del siguiente punto disponible en la pila.

La pila es un área en la memoria que está reservada para almacenar una pila, que es un tipo de contenedor LIFO (último en entrar primero), donde almacenamos las variables locales y la dirección de retorno, lo que permite una administración simple de la anidación de llamadas de función en un programa típico.

Vea este artículo de Wikipedia para una explicación básica de la gestión de pila.


Un puntero de pila es un pequeño registro que almacena la dirección de la parte superior de la pila. Se usa con el propósito de señalar la dirección de la parte superior de la pila.


Una pila es un LIFO (último en entrar, primero en salir; la última entrada que ingresas en la pila es la primera que obtienes al hacer pop) estructura de datos que normalmente se usa para mantener los cuadros de pila (bits de la pila que pertenecen a la función actual).

Esto incluye, pero no está limitado a:

  • la dirección del remitente.
  • un lugar para un valor de retorno.
  • parámetros pasados
  • variables locales

Empujas los artículos a la pila y los quitas. En un microprocesador, la pila se puede utilizar para datos de usuario (como variables locales y parámetros pasados) y datos de CPU (como direcciones de retorno cuando se llaman subrutinas).

La implementación real de una pila depende de la arquitectura del microprocesador. Puede crecer hacia arriba o hacia abajo en la memoria y puede moverse antes o después de las operaciones push / pop.

La operación que típicamente afecta la pila es:

  • subrutina llama y regresa.
  • interrumpir llamadas y devoluciones.
  • código que explícitamente empuja y estalla las entradas.
  • manipulación directa del registro SP.

Considere el siguiente programa en mi lenguaje ensamblador (ficticio):

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

Ahora sigamos la ejecución, describiendo los pasos que se muestran en los comentarios anteriores:

  1. Esta es la condición inicial donde el contador del programa es cero y el puntero de la pila es 8000 (todos estos números son hexadecimales).
  2. Esto simplemente carga el registro r0 con el valor inmediato 7 y avanza al siguiente paso (supongo que comprende que el comportamiento predeterminado será pasar al siguiente paso a menos que se especifique lo contrario).
  3. Esto empuja a r0 hacia la pila reduciendo el puntero de la pila en dos y luego almacenando el valor del registro en esa ubicación.
  4. Esto llama una subrutina. Lo que hubiera sido el contador del programa se empuja a la pila de una manera similar a r0 en el paso anterior y luego el contador del programa se establece en su nuevo valor. Esto no es diferente de un impulso a nivel de usuario que no sea el hecho de que se hace más a nivel de sistema.
  5. Esto carga r1 desde una ubicación de memoria calculada desde el puntero de la pila: muestra una forma de pasar los parámetros a las funciones.
  6. El enunciado de retorno extrae el valor de donde señala el puntero de pila y lo carga en el contador de programa, ajustando el puntero de pila al mismo tiempo. Esto es como un pop de nivel de sistema (ver siguiente paso).
  7. Saltar r0 de la pila implica extraer el valor de donde apunta el puntero de pila y luego ajustar ese puntero de pila.
  8. Las instrucciones de detención simplemente dejan el contador de programa donde está, un tipo de bucle infinito.

Es de esperar que a partir de esa descripción, quede claro. La conclusión es: una pila es útil para almacenar el estado de una manera LIFO y esto es generalmente ideal para la forma en que la mayoría de los microprocesadores realizan llamadas de subrutinas.

A menos que seas un SPARC por supuesto, en cuyo caso usas un buffer circular para tu pila :-)

Actualización: solo para aclarar los pasos que se deben seguir cuando se presionan y aparecen valores en el ejemplo anterior (explícitamente o por llamada / devolución), consulte los ejemplos siguientes:

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 | | | | | | | | | | | | | | | | | | | +--------+ +--------+ +--------+