Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
LA PILA (STACK)
Introduccin
Muchas veces los programas requieren, como parte de su ejecucin, almacenar informacin de
manera temporal (por ejemplo, una serie de nmeros), para ser utilizada en algn otro momento,
luego de lo cual esa informacin puede ser descartada, pues no se requiere ms. Podra hacerse esto
utilizando registros del microcontrolador, pero el nmero de registros que tiene es limitado. Podra
usarse un registro especfico de memoria RAM por cada nmero, pero esto no es muy prctico,
pues una vez descartada la informacin, lo ideal es que ese registro pueda ser reutilizado para
almacenar algn otro tipo de informacin, y adems, la cantidad de informacin que se requiera
almacenar puede variar conforme se ejecuta el programa.
La pila es una forma de almacenamiento temporal de datos (estructura de datos) que permite el
almacenamiento de datos y su recuperacin, permitiendo que, una vez recuperada la informacin,
dicho espacio pueda ser reutilizado.
Para tener una idea de lo que es una pila, veamos dos ejemplos.
La cacerina de una pistola:
En la cacerina de una pistola (lugar donde van las balas), se introducen las balas por la parte
superior. Cuando se dispara, la primera bala que sale es la ltima que se coloc. Adems de esto,
tiene las siguientes caractersticas:
Las balas se insertan por la parte superior, de una en una.
Las balas salen slo por la parte superior, una por una.
De todas las balas insertadas, la primera en salir es la ltima que se insert.
La nica manera de que salga una bala que no sea la superior, es sacando las que estn encima de
sta primero.
Es imposible insertar una bala entre otras dos que ya estn en la cacerina.
El nmero de balas en la cacerina no es fijo, puede haber una o ms, pero siempre se debe
insertar por arriba, y salir por arriba.
Aunque puede haber un nmero cualesquiera, hay un nmero mximo de balas que pueden
insertarse en la cacerina.
Los conos de CDs:
En realidad son cilindros con 50 o 100 discos CD-R en blanco, en
los cuales estn los CDs uno encima del otro. Slo pueden
sacarse los CDs por la parte superior, y si se quiere insertar un
CD en el cilindro, tiene que hacerse por la parte superior.
Ambos ejemplos corresponden a una pila tipo LIFO (Last Input,
First Output), que significa: "ltimo en entrar, primero en salir".
Es este tipo de pila el utilizado en los microprocesadores y
microcontroladores.
Fig. 1.- Un "cono" de CD's
LaPila ver 1.9
-1-
17/08/2012
Es debido a la existencia de estas estructuras, que existen las subrutinas y procedimientos en los
lenguajes de alto nivel. Si los CPUs no pudiesen trabajar con estas estructuras no existiran los
lenguajes tales como Pascal, C, Basic.
Operaciones con pilas
Las operaciones que se pueden realizar con una pila son dos: poner, y sacar.
poner (push): Inserta un nuevo elemento en la pila. Ello significa que la pila crecer (tendr un
elemento ms).
sacar o extraer (pull, pop): Extrae un elemento de la pila. Al sacar un elemento, el tamao de la
pila disminuye en una unidad. El espacio que estuvo ocupado por dicho elemento puede ser
reutilizado.
En la figura se muestra las operaciones poner (push) y sacar (pull).
PUSH (poner)
A
A
B
C
D
B
C
D
A
B
C
D
B
C
D
La pila en un computador
En un computador, la pila es una regin de memoria RAM. En el caso de computadores basados en
microcontroladores con arquitectura Harvard hay dos variantes: En algunos microcontroladores la
pila es una zona de la memoria de datos (es el caso del ATmega88), y en otros, es una memoria
especial, independiente de la memoria de datos (es el caso del microcontrolador PIC16F872 de
Microchip, que slo permite almacenar 8 valores en la pila).
En los computadores, cuando se sacan datos de la pila, stos no desaparecen, pues realmente se
efecta una lectura de la memoria, pero si el programa pone un nuevo valor en la pila entonces
sobrescribir en ese lugar, pues ya se haba descartado el valor anterior.
LaPila ver 1.9
-2-
17/08/2012
-3-
17/08/2012
e004
bf0e
e50f
bf0d
000004 e8e0
000005 e7f6
000006 93ef
000007 93ff
000008 91ef
000009 91ff
00000a cfff
ldi
r16, high($4FF) ; configuramos la pila: SP=$04FF
out
SPH, r16
ldi
r16, low($4FF)
out
SPL, r16
; colocamos valores iniciales para R30 y R31
ldi
r30, $80
ldi
r31, $76
; almacenamos los nmeros en la pila
push
r30
push
r31
; sacamos los nmeros de la pila
pop
r30
pop
r31
fin:
rjmp
fin
La siguiente figura muestra el estado de la pila, y los registros R30 y R31, segn se ejecuta el
programa.
La figura a) muestra el contenido de los registros antes de que se ejecute el programa. El puntero de
pila tiene el valor $0000, pues ese es el valor que siempre tiene luego de salir del estado de inicio
(reset). Los contenidos de los registros R30 y R31 se han representado con X, indicando que an no
se les ha escrito un valor. Aqu est la descripcin en secuencia, indicndose las direcciones de las
instrucciones:
Direcciones $0000 a $0003. Se pone un valor inicial al puntero de pila (SP), definindose
con ello el inicio de la pila. El valor colocado est definiendo la direccin de memoria ms
alta que se emplear para la pila, pues sta crece hacia direcciones bajas de memoria.
Normalmente en un programa esto se hace una sola vez, pues luego de esta configuracin
inicial, el microcontrolador modifica automticamente el contenido de este registro. El valor
escrito ($4FF) es el primer lugar a usar de la pila. El siguiente ser la direccin $4FE. La pila
luce como se indica en la Fig. 4 b).
Direcciones $00004 y $0005. Se ponen los valores a los registros R30 y R31 (Fig. 4c)
Direccin $0006. Se pone en la pila el contenido de R30. El CPU graba el contenido de R30
en la direccin indicada por el puntero de pila SP, en este caso $45F, y luego decrementa el
puntero de pila. La pila luce como se indica en la Fig. 4d. Observar que el puntero de pila
siempre est apuntando a la siguiente posicin disponible de la pila.
Direccin $0007. Se pone en la pila el contenido de R31. La pila ahora est como se indica
en la Fig. 4e). la siguiente posicin disponible es la direccin $45D. En este momento hay
dos nmeros en la pila.
Direccin $0008. Se saca un valor de la pila (el ltimo puesto), y se graba en R30. El CPU
primero incrementa el puntero de pila a $45E, y luego carga el valor $76 contenido en la
direccin $45E en el registro R30. La pila est ahora como se indica en la Fig. 4f).
-4-
17/08/2012
Direccin $0009. Se saca un valor de la pila (el que se puso primero) y se graba en R31. El
CPU carga el valor $80 contenido en la direccin $45F en el registro R31. Nuevamente el
puntero de pila SP apunta a la direccin $45F (Fig. 4g). Ahora la pila est vaca.
Direccin $000A. Lazo infinito, pues sino, el CPU ejecutara lo que encuentre en las otras
direcciones de la memoria de programa.
Con las dos instrucciones POP se complet el intercambio de valores de los registros R30 y R31.
-5-
17/08/2012
Puede verse que realmente los valores "sacados" de la pila permanecen en la memoria, lo cual es
lgico pues "extraer" un valor de la pila equivale a una lectura de memoria y modificacin del
puntero de pila. Sin embargo, es una muy mala costumbre el querer leer directamente un valor de la
pila una vez que ste se ha sacado con una instruccin de PULL. Las razones de ello estn
relacionadas con el manejo de interrupciones, que es tema de otro captulo.
Manejo de la pila en el ATmega88
Cargar un valor inicial en el puntero de pila
Para cargar un valor inicial, hay que copiar la direccin de inicio de la pila en los registros de E/S
SPH y SPL. Esto puede hacerse de dos maneras.
a) Usando las direcciones del espacio de E/S
Por ejemplo, si se quiere tener SP= $4FF
Si no se utiliza el archivo de extensin .inc (que para el ATmega88 es m88def.inc), en el que
estn definidos los nombres para los registros de E/S con direcciones $3D y $3E, debera de hacerse
como se indica en este caso:
.EQU
.EQU
.EQU
...
ldi
out
ldi
out
.....
SPH = $3E
SPL = $3D
RAMEND = $4FF
R16,
SPH,
R16,
SPL,
high(RAMEND)
R16
low(RAMEND)
R16
Si se incluye dicho archivo, basta con escribir lo que est en negrita. No es necesario definir los
registros con la directiva .EQU pues stos ya estn en el archivo m88def.inc.
...
ldi
out
ldi
out
.....
R16,
SPH,
R16,
SPL,
high(RAMEND)
R16
low(RAMEND)
R16
SPL:
SPH:
.equ
.dseg
.org
.byte
.byte
...
.cseg
ldi
sts
ldi
sts
pila = $4FF
$5D
1
1
R16,
SPH,
R16,
SPL,
-6-
17/08/2012
.....
Si se utiliza el archivo m8def.inc, no debe usarse este mtodo, pues ya estn predefinidos los valores
para SPH y SPL, y lo son para las direcciones del espacio de E/S.
Observaciones
El puntero de pila debe apuntar a direcciones de memoria RAM. Por ello, debera ser alguna
direccin en el rango $100 a $4FF en el ATmega88. Como las pila crece hacia direcciones bajas de
memoria, es preferible que comience en la direccin ms alta de memoria RAM, en el caso del
ATmega88, $4FF.
Se ha visto en el ejemplo que los valores sacados, realmente permanecieron en la memoria, pues
sacar un nmero equivale a efectuar una lectura de memoria. Sin embargo, es preferible pensar
que dichos nmeros ya no estn. Querer leer valores que ya fueron extrados de la pila, es una
causa de frecuentes fallas de programas (bugs), especialmente cuando se trabaja con interrupciones,
tema de otro captulo.
Otro error frecuente al programar es sacar ms valores de los que se han insertado en la pila, o
viceversa.
Las instrucciones PUSH y POP no modifican las banderas.
-7-
17/08/2012