Está en la página 1de 3

Lenguaje de interfaz

Manipulación de la Pila

Uso del Stack

El Stack es un segmento especial de memoria que opera en conjunción con varias


instrucciones del 8086. Como con todos los segmentos, la localización del stack y su
tamaño (hasta 64K) dependen del programador determinarlo. En los programas de
lenguaje ensamblador, la forma más fácil de crear un stack es usar la directiva STACK. Un
stack tiene tres propósitos principales:

- Preservar valores de los registros temporalmente.


- Almacenar direcciones al las cuales las rutinas regresaran.
- Almacenar variables dinámicas.

El último de éstos viene a jugar más frecuentemente en los lenguajes de programación


de alto nivel, donde las variables son pasadas vía stack hacia y desde, funciones y
procedimientos. Similarmente, variables temporales pueden se almacenadas en el stack.
Estos usos son raros en la programación pura en lenguaje ensamblador, aunque se puede
almacenar variables de memoria de ésta manera si se desea.

Como opera el Stack

Conceptualmente, un stack es como una torre de platos en una cocina de un


restaurante. El plato de encima de la pila está fácilmente disponible. Pero para tomar los
platos de abajo, otros platos de encima primeramente deben ser removidos. Colocar un
nuevo plato en la pila es llamado push, Remover un plato de la parte superior de la pila,
es llamado pop. Ya que de la manera en que el último plato colocado en el stack es el
primer plato disponible a ser removido, éste tipo de stack es llamado stack LIFO o UEPS,
por "Last-In-First-Out".

No como los platos, los valores en la computadora no pueden moverse físicamente


hacia arriba y hacia abajo. Por lo tanto, para simular la acción de un movimiento de los
valores del stack, requiere de utilizar registros para localizar la dirección base del Stack y la
dirección OFFSET del plato superior - que es, la localidad donde el valor superior de la pila
es almacenado. En programación 8086, el registro segmento ss direcciona al segmento
de stack base. El registro sp direcciona el desplazamiento OFFSET tope del Stack en dicho
segmento.

La siguiente figura Ilustra como aparece un stack de 12 bytes en memoria. EL registro ss


direcciona la base del stack en el segmento direccionado en 0F00. El registro sp
direcciona el desplazamiento (OFFSET) desde esta dirección inicial, en un rango desde
0000 hasta 000A. El ultimo byte del stack esta en desplazamiento 000B. Los elementos en el
stack ocupan palabras de 2 Bytes. El programa que prepara éste stack puede declarar
STACK 12 y dejar que el ensamblador, enlazador, y DOS calculen exactamente donde
estará almacenado el Stack en memoria. No hay que inicializar ss y sp. DOS lo realiza por
nosotros cuando carga el programa para ejecutarlo. En la figura, sp1 muestra donde
apunta sp cuando el programa comienza a correr. Nótese que la dirección lógica en
ss:sp apunta al byte por debajo del ultimo byte en el stack.

Página 1 de 3
Lenguaje de interfaz
Manipulación de la Pila

Memoria Baja
0000 0F00:
0002
0004
0006
0008 200 ss:sp3
000A 100 ss:sp2
000C ss:sp1
Fin del segmento Stack

En referencia al la figura anterior. Varias acciones ocurren si se ejecutan las siguientes


instrucciones:

mov ax,100
push ax ; sp2
mov bx, 200
push bx ; sp3

La instrucción push realiza dos pasos:

1. Substrae 2 de sp
2. El valor del registro especificado es copiado a [ss:sp].

El orden de estos pasos es importante. Un push primero substrae 2 (no 1) de sp. La primer
colocación push, deja a sp en sp2, donde el valor del registro ax es almacenado. Nótese
que esta acción deja al puntero del stack direccionado al valor palabra recientemente
colocado- pushed- en el stack.

Manipulación del Stack

El punto principal de la manipulación del stack es simple: Para cada push en un


programa, debe haber su correspondiente pop. Igualando pops y pushes mantiene el
stack en forma correcta- en otras palabras, en sincronización con la habilidad del
programa para almacenar y recuperar el valor que necesita.

Considere lo que sucede si se falla en ejecutar un correspondiente pop para cada


push. En éste caso, pushes futuros causarán que el stack crezca mas y más largo,
eventualmente rebasando el espacio segmento permitido para el programa. Este grave
error normalmente termina en un crash sobre escribiendo otras áreas de memoria por el
puntero del stack. Un error similar ocurre si se ejecutan más pops que pushes, causando un
bajoflujo y también resultar en un crash.

Página 2 de 3
Lenguaje de interfaz
Manipulación de la Pila

Una forma de prevenir éstos problemas es escribir los programas en pequeños módulos, o
subrutinas. En cada modulo, realizar un push con todos los registros que se utilizarán.
Entonces, justo antes de que ésta sección de código termine, realizar un pop a los mismos
registros retirándolos pero en orden inverso.

push ax
push bx
push cx

; ------ Programa objetivo

pop cx
pop bx
pop ax

En éste ejemplo, los registros ax, bx y cx, son posiblemente utilizados; por lo tanto, éstos
registros son almacenados en el stack para preservar los valores de los registros. Por último,
los valores son retirados (pop) del stack en orden inverso, restaurando los valores originales
de los registros y manteniendo el stack en sincronía.

PUSH y POP realizan las operaciones de apilado y desapilado en la pila del procesador
respectivamente, admiten todos los tipos de direccionamiento (excepto inmediato). Los
operandos deben ser siempre de 16 bits.

PUSH reg
PUSH mem
PUSH seg-reg
POP reg
POP mem
POP seg-reg

Ejemplos:
PUSH AX ; envía a la pila AX
POP DS ; carga el primer elemento de la pila en DS

Página 3 de 3

También podría gustarte