Un registro de pila es un registro del procesador central de una computadora cuyo propósito es realizar un seguimiento de una pila de llamadas . En una máquina con arquitectura basada en acumuladores , este puede ser un registro dedicado. En una máquina con múltiples registros de propósito general , puede ser un registro que está reservado por convención, como en la arquitectura IBM System/360 a través de z/Architecture y las arquitecturas RISC , o puede ser un registro que las instrucciones de llamada a procedimiento y retorno están programadas para usar, como en las arquitecturas PDP-11 , VAX e Intel x86 . Algunos diseños como Data General Eclipse no tenían un registro dedicado, sino que usaban una dirección de memoria de hardware reservada para esta función.
Las máquinas anteriores a finales de los años 1960 (como la PDP-8 y la HP 2100 ) no tenían compiladores que admitieran la recursión . Sus instrucciones de subrutina normalmente guardaban la ubicación actual en la dirección de salto y luego establecían el contador del programa en la siguiente dirección. [1] Si bien esto es más simple que mantener una pila, dado que solo hay una ubicación de retorno por sección de código de subrutina, no puede haber recursión sin un esfuerzo considerable por parte del programador.
Una máquina de pila tiene 2 o más registros de pila: uno de ellos realiza un seguimiento de una pila de llamadas , el otro u otros realizan un seguimiento de otras pilas .
En 8086 , el registro principal de la pila se denomina "puntero de pila" (SP). El registro de segmento de pila (SS) se utiliza normalmente para almacenar información sobre el segmento de memoria que almacena la pila de llamadas del programa que se está ejecutando actualmente. SP apunta a la parte superior de la pila actual. De forma predeterminada, la pila crece hacia abajo en la memoria, por lo que los valores más nuevos se colocan en direcciones de memoria inferiores. Para guardar un valor en la pila, PUSH
se utiliza la instrucción. Para recuperar un valor de la pila, POP
se utiliza la instrucción.
Ejemplo : Supongamos que SS = 1000h y SP = 0xF820. Esto significa que la parte superior de la pila actual es la dirección física 0x1F820 (esto se debe a la segmentación de memoria en 8086 ). Las siguientes dos instrucciones de máquina del programa son:
Hacha de empuje Caja de empuje
Esto ilustra cómo funciona PUSH. Normalmente, el programa en ejecución envía registros a la pila para utilizarlos con otros fines, como llamar a una rutina que puede cambiar los valores actuales de los registros. Para restaurar los valores almacenados en la pila, el programa debe contener instrucciones de máquina como esta:
POP BOX POP HACHA
POP BX
copia la palabra en 0x1F81C (que es el valor antiguo de BX) a BX, luego aumenta SP en 2. SP ahora es 0xF81E.POP AX
copia la palabra en 0x1F81E a AX, luego establece SP en 0xF820. [nb 1] [nb 2]Los procesadores más simples almacenan el puntero de pila en un registro de hardware normal y utilizan la unidad lógica aritmética (ALU) para manipular su valor. Normalmente, push y pop se traducen en múltiples microoperaciones para sumar o restar por separado el puntero de pila y realizar la carga o el almacenamiento en la memoria. [3]
Los procesadores más nuevos contienen un motor de pila dedicado para optimizar las operaciones de pila. Pentium M fue el primer procesador x86 en introducir un motor de pila. En su implementación, el puntero de pila se divide entre dos registros: ESP O , que es un registro de 32 bits, y ESP d , un valor delta de 8 bits que se actualiza directamente mediante operaciones de pila. Los códigos de operación PUSH, POP, CALL y RET operan directamente con el registro ESP d . Si ESP d está cerca de desbordarse o se hace referencia al registro ESP desde otras instrucciones (cuando ESP d ≠ 0), se inserta una microoperación de sincronización que actualiza ESP O utilizando la ALU y restablece ESP d a 0. Este diseño ha permanecido en gran parte sin modificaciones en los procesadores Intel posteriores, aunque ESP O se ha ampliado a 64 bits. [4]
En la microarquitectura AMD K8 también se adoptó un motor de pila similar al de Intel . En Bulldozer , se eliminó la necesidad de microoperaciones de sincronización, pero no se conoce el diseño interno del motor de pila. [4]
PUSH
& POP
solo pueden funcionar con elementos de 16 bits.La mayoría de las computadoras guardan la dirección de retorno en la pila, en uno de los registros o en la primera palabra del procedimiento (en cuyo caso la primera instrucción ejecutable del procedimiento debe almacenarse en la segunda palabra). Si se utiliza este último método, un retorno del procedimiento es un salto a la ubicación de memoria cuya dirección está contenida en la primera palabra del procedimiento.(xiv+294+4 páginas)