--------------------------------------------------------------------------------------------------------------------------
Un "Stack" es bloque consecutivo de datos almacenados por el programador. Este bloque de memoria puede ser utilizado tanto por el control interno del microcontrolador como por el programador para almacenar datos temporalmente. La pila funciona con un mecanismo tipo LIFO, lo último que se almacena en la pila es lo primero que se recupera de la pila.
Estructura de una Stack-LIFO(Proceso de PUSH y POP) |
Esta pila tiene un apuntador conocido como Stack Pointer o SP, el funcionamiento de la pila en el microcontrolador AVR es muy sencillo, la posicion inicial es la dirección superior es decir que si la pila tuviera 100 espacios la primera posicion sería la 100, cuando se almacena un registro en la pila entonces el apuntador disminuye en 1 de manera que el siguiente dato se almacene en la siguiente posicion es decir para nuestro ejemplo sería en la posición 99 así sucesivamente, cuando se saca un dato el SP aumenta para poder sacar el dato siguiente.
La capacidad de la pila cambiará de acuerdo con la referencia del microcontrolador que se esté utilizando, pero en general los microcontroladores AVR necesitan 16 bits para direccionamiento de la Pila, debido a que el microcontrolador AVR es de 8 bits entonces se hace necesario utilizar dos registros para el SP, estos son el SPH y el SPL (high and low) y se refieren a los bits mas significativos y menos significativos respectivamente.
Una pila es un búfer (LIFO), que contiene una cantidad de elementos de datos generalmente implementados como un bloque de n bytes consecutivos.
La dirección del último elemento de datos que se colocará en la pila se señala mediante el puntero de pila (sp)
Aplicación de pilas:
- Almacenamiento temporal de variables.
- Almacenamiento temporal de direcciones de programas
- Comunicación con subrutinas.
La CPU necesita esta área de almacenamiento porque solo hay un número limitado de registros
--------------------------------------------------------------------------------------------------------------------------
En un micro AVR, SP es un registro independiente para propositos de STACK.
SP es un registro especial donde se necesita para operaciones en STACK.
SP es de 16 bits de ancho y se implementa como dos registros que son SPH y SPL.
El registro SPH presenta el byte alto de SP mientras que el registro SPL presenta el byte inferior.
Tanto SPH como SPL tienen 8 bits de ancho.
El SP debe ser lo suficientemente ancho para dirigirse a toda la RAM.
En los AVR con más de 256 bytes de memoria, SP se compone de dos registros de 8 bits (SPL y SPH)
En AVR con menos de 256 bytes de memoria, SP está hecho de sólo registro SPL.
Registro SP |
--------------------------------------------------------------------------------------------------------------------------
Es una intrucción para llenar de datos temporales en la memoria SRAM.
1-->Se escribe en Stack el dato(en la parte de arriba) , memory[stack]<~~DR(registro de datos)
2-->disminuye SP, SP<~~SP-1
![]() |
Estado inicial |
Push R16
![]() |
Después de Push R16 |
LDI R17,0x25
Push R17![]() |
Después de Push R17 |
Push R18
![]() |
Después de Push R18 |
-Recordemos que la memoria en $DF es mayor que $DC($DF>$DC).
-En AVR, la pila(STACK) crece de una ubicación de memoria superior a una ubicación de memoria inferior.
-Así, es común inicializar el SP a la ubicación de memoria más alta.
-El puntero de Pila apunta al área de pila de la SRAM de datos donde se localizan la pila de interrupción y de subrutina. Este espacio de la pila en la SRAM de datos debe ser definido por el programa antes de que se ejecute cualquier llamada a subrutina o se habiliten interrupciones. El puntero de pila debe estar a set para apuntar por encima de $60.
>>>POP
Es una intrucción para sacar datos temporales de la memoria SRAM
1-->Incrementa SP, SP<~~SP+1
2-->Lee la posicición de stack(parte de arriba ) y copia al destino,
DR(registro de datos) <~~Memoria(Stack).
Ejemplo de STACK?
--------------------------------------------------------------------------------------------------------------------------
2)
(LLENADO DE STACK)
PUSH AX ; Coloca Ax en STACK
PUSH BX ; Coloca Bx en STACK
PUSH CX ; Coloca Cx en STACK
PUSH DX ; Coloca Dx en STACK
PUSH SI ; Coloca SI en STACK
PUSH DI ; Coloca DI en STACK
--------
--------; Código que modifica AX,BX,CX,DX,SI,DI
--------
(RECUPERACIÓN DE LOS VALORES DE STACK)
POP DI ; restaura el valor original de DI
POP SI ; restaura el valor original de SI
POP DX ; restaura el valor original de DX
POP CX ; restaura el valor original de CX
POP BX ; restaura el valor original de BX
POP AX ; restaura el valor original de AX
RAMEND?
--------------------------------------------------------------------------------------------------------------------------
Es una intrucción para sacar datos temporales de la memoria SRAM
1-->Incrementa SP, SP<~~SP+1
2-->Lee la posicición de stack(parte de arriba ) y copia al destino,
DR(registro de datos) <~~Memoria(Stack).
Para recuperar un byte de datos de la pila usamos la
instrucción POP.
POP R18
![]() |
Después de POP R18 |
POP R17
![]() |
Después de POP R17 |
POP R16
![]() |
Después de POP R16 |
Ejemplo de STACK?
--------------------------------------------------------------------------------------------------------------------------
1)
Este ejemplo muestra el STACK y SP(Stack Pointer) y el registro usado despues de la ejecución de cada instrución.
.INCLUDE "M32DEF.INC"
.ORG 0
LDI R16,HIGH(RAMEND)
OUT SPH,R16
LDI R16,LOW(RAMEND)
OUT PL,R16
LDI R31,0
LDI R20,0x21
LDI R22,0x66
PUSH R20
PUSH R22
LDI R20,0
LDI R22,0
POP R22
POP R31
![]() |
Funcionamiento de STACK y STACK POINTER(SP) |
(LLENADO DE STACK)
PUSH AX ; Coloca Ax en STACK
PUSH BX ; Coloca Bx en STACK
PUSH CX ; Coloca Cx en STACK
PUSH DX ; Coloca Dx en STACK
PUSH SI ; Coloca SI en STACK
PUSH DI ; Coloca DI en STACK
--------
--------; Código que modifica AX,BX,CX,DX,SI,DI
--------
(RECUPERACIÓN DE LOS VALORES DE STACK)
POP DI ; restaura el valor original de DI
POP SI ; restaura el valor original de SI
POP DX ; restaura el valor original de DX
POP CX ; restaura el valor original de CX
POP BX ; restaura el valor original de BX
POP AX ; restaura el valor original de AX
RAMEND?
--------------------------------------------------------------------------------------------------------------------------
RAMEND es una etiqueta que representa la dirección de la última ubicación de memoria en SRAM. Para usar esta etiqueta, debe asegurarse de incluir el archivo de encabezado de definición para el microcontrolador específico.
Las funciones low () y high () son utilizadas por el ensamblador para devolver el byte bajo y el byte alto respectivamente de una palabra de 16 bits. Recuerde que estamos tratando con un microcontrolador de 8 bits que solo puede manejar solo 8 bits a la vez. RAMEND es una palabra de 16 bits y por eso usamos las funciones para dividirla.
.include "M32DEF.Inc"
LDI R16,low(RAMEND)
OUT SPL,R16
LDI R16,high(RAMEND)
OUT SPH,R16
Conclusión
--------------------------------------------------------------------------------------------------------------------------- El puntero de pila es decrementado en 1 cuando los datos se introducen en la pila con la instrucción PUSH y es decrementado en 2 cuando una dirección se introduce en la pila con llamadas a subrutinas e interrupciones. El puntero de pila es incrementado en 1 cuando el dato se saca de la pila con la instrucción POP y es incrementado en 2 cuando una dirección se saca de la pila con retorno de subrutina RET o retorno de interrupción RETI.
- El rango que abarcará nuestra Pila /Stack y Stack Pointer depende del microcontrolador por ejemplo:
No hay comentarios:
Publicar un comentario