Un registro de pila es un registro de procesador central de computadora cuyo propósito es realizar un seguimiento de una pila de llamadas . En una máquina de arquitectura basada en acumuladores , esto puede ser un registro dedicado como SP en una máquina Intel x86 . En una máquina de registro general , puede ser un registro reservado por convención, como en las máquinas PDP-11 o RISC . Algunos diseños como el Data General Eclipse no tenían registro dedicado, pero usaban una dirección de memoria de hardware reservada para esta función.
Las máquinas anteriores a finales de la década de 1960, como PDP-8 y HP 2100, no tenían compiladores que admitieran la recursividad . Sus instrucciones de subrutina normalmente guardarían la ubicación actual en la dirección de salto y luego establecerí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 recursividad 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 realiza un seguimiento de otras pilas .
Apilar registros en x86
En 8086 , el registro de pila principal se denomina puntero de pila - SP. El registro de segmento de pila (SS) se usa generalmente para almacenar información sobre el segmento de memoria que almacena la pila de llamadas del programa actualmente ejecutado. 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 más bajas. Para enviar un valor a la pila, PUSH
se utiliza la instrucción. Para sacar un valor de la pila, POP
se usa la instrucción.
Ejemplo : suponiendo 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 la memoria en 8086 ). Las siguientes dos instrucciones de máquina del programa son:
PUSH AX PUSH BX
- Esta primera instrucción empujará el valor almacenado en AX (registro de 16 bits) a la pila. Esto se hace restando un valor de 2 (2 bytes) de SP.
- El nuevo valor de SP se convierte en 0xF81E. Luego, la CPU copia el valor de AX a la palabra de memoria cuya dirección física es 0x1F81E.
- Cuando se ejecuta "PUSH BX", SP se establece en 0xF81C y BX se copia en 0x1F81C. [2]
Esto ilustra cómo funciona PUSH. Por lo general, el programa en ejecución empuja los 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 la máquina como esta:
POP BX POP HACHA
Motor de pila
Los procesadores más simples almacenan el puntero de la pila en un registro de hardware normal y utilizan la unidad lógica aritmética (ALU) para manipular su valor. Por lo general, push y pop se traducen en múltiples microoperaciones , para sumar / restar por separado el puntero de la pila y realizar la carga / 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 en 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 un micro-op de sincronización que actualiza el ESP O usando la ALU y restablece ESP d a 0. Este diseño se ha mantenido en gran medida sin modificaciones en los procesadores Intel posteriores, aunque ESP O se ha ampliado a 64 bits. [4]
También se adoptó un motor de pila similar al de Intel en la microarquitectura AMD K8 . En Bulldozer , se eliminó la necesidad de sincronizar microoperaciones, pero se desconoce el diseño interno del motor de pila. [4]
Notas
Referencias
- ^ Salomon, David (febrero de 1993) [1992]. Escrito en la Universidad Estatal de California, Northridge, California, EE. UU. Chivers, Ian D. (ed.). Ensambladores y cargadores (PDF) . Serie Ellis Horwood en Computadoras y sus aplicaciones (1 ed.). Chicester, West Sussex, Reino Unido: Ellis Horwood Limited / Simon & Schuster International Group . ISBN 0-13-052564-2. Archivado (PDF) desde el original el 23 de marzo de 2020 . Consultado el 1 de octubre de 2008 .
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 usa el ú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) - ^ Howard, Brian. "Tutorial de montaje - Instrucciones" . Departamento de Ciencias de la Computación, Universidad DePauw . Consultado el 19 de julio de 2013 .
- ^ Stokes, Jon "Hannibal" (25 de febrero de 2004). "Una mirada al núcleo de Centrino: el Pentium M" . archive.arstechnica.com . pag. 5.
- ^ a b Niebla, Agner. "La microarquitectura de las CPUs Intel, AMD y VIA" (PDF) . Universidad Técnica de Dinamarca.