domingo, 14 de octubre de 2018

Stack o Pila - SP(Stack Pointer) ¿?

Qué es un Stack?
--------------------------------------------------------------------------------------------------------------------------
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

Qué es un SP?
--------------------------------------------------------------------------------------------------------------------------
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

Operaciones en STACK(PUSH-POP)
--------------------------------------------------------------------------------------------------------------------------

>>>PUSH
      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
 LDI R16,0x33
 Push R16

Después de Push R16



LDI R17,0x25
Push R17


Después de Push R17
LDI R18,0x20
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).

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)
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?
--------------------------------------------------------------------------------------------------------------------------
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

Uso del firmware original de la grabadora USBasp AVR en MX-USBASP (clon chino)

Te vendieron un USBisp pensado que es un USBasp?? Hace 2 meses compré un "USBasp" fui a probarlo y no funcionó....pensé me estafar...