Pilha, Stack Pointer e Sub-rotinas
Prof. Roberto de Matos
roberto.matos@ifsc.edu.br
09/2019
Entender o que ´ e e como funciona uma pilha de microcontrolador Praticar com as instru¸ c˜ oes do AVR que manipulam a pilha Criar Sub-rotinas
Entender o que ´ e salvar o contexto e passar parˆ ametros Leitura Recomendada:
AVR e Arduino: T´ ecnicas de Projeto, 2 ª ed. (Se¸ c˜ ao 2.1.2)
11
Alguns exemplos e imagens dessa apresenta¸ c˜ ao s˜ ao retirados desse livro.
Pilha e Stack Pointer
Pilha:
- Utiliza parte da SRAM
- Armazena temporariamente dados de vari´ aveis locais e retorno de sub-rotinas/interrup¸ c˜ oes.
Stack Pointer (SP, Ponteiro de Pilha):
- P´ os-decrementado quando um dado ´ e adicionado na pilha.
- Pr´ e-incrementado quando um dado ´ e retirado da pilha - SP deve ser inicializado para o ´ ultimo endere¸ co da RAM
- O ATmega328 o endere¸co ´ e 0x8FF e j´ a ´ e carregado durante o reset.
- Alguns uC da fam´ılia ATmega precisam ter o SP inicializado pelo
programador.
Pilha e Stack Pointer
Instru¸c˜ao SP Descri¸c˜ao
PUSH Decrementa em 1 Um dado ´ e colocado na pilha (1 byte).
CALL O endere¸ co de retorno ´ e colocado na pilha quando ICALL Decrementa em 2 uma chamada de sub-rotina ou interrup¸ c˜ ao acontece
RCALL (o endere¸ co possui 2 bytes).
POP Incrementa em 1 O dado do topo da pilha e retirado (1 byte).
RET Incrementa em 2 O endere¸ co de retorno ´ e retirado da pilha quando RETI se retorna de uma sub-rotina ou interrup¸ c˜ ao
(o endere¸ co possui 2 bytes).
Exemplo: Salvando o contexto dos registradores modificados
1 .INCLUDE "m328pdef.inc"
2 main:
3 ;Inicializa¸c~ao do Stack Pointer deve ser feita com o endere¸co final da SRAM 4 ; N~AO ´E NECESS´ARIO NO ATmega328
5 ldi r16, HIGH(RAMEND)
6 out sph, r16 ;registrador SPH = parte alta do endere¸co 7 ldi r16, LOW(RAMEND)
8 out spl, r16 ;registrador SPL = parte baixa do endere¸co 9
10 rcall delay 11 rjmp main 12
13 delay:
14 push SREG ; Salva os valores de SREG e 15 push r16 ; ... r16 e
16 push r17 ; ... r17 na pilha 17
18 ; Executa sub-rotina : 19 clr r16
20 clr r17 21 loop:
22 dec r16 ; decrementa r16, come¸ca com o valor 0x00
23 brne loop ; enquanto r16 > 0 fica decrementando r16, desvio para Atraso 24 dec r17 ; decrementa r17, come¸ca com o valor 0x00
25 brne loop ; enquanto r17 > 0 volta a decrementar r16 26
27 pop r16 ; Restaura os valores de r16 28 pop r17 ; ... r17
29 pop SREG ; ... SREG da pilha 30 ret ; retorno da sub-rotina
1 .INCLUDE "m328pdef.inc"
2 main:
3 ldi r16, 0xAA 4 ldi r17, 0xBB 5 rcall delay_variavel 6 rjmp main
7
8 delay_variavel:
9 push SREG ; Salva o valor de SREG na pilha 10
11 ; Executa sub-rotina : 12 loop:
13 dec r16 ; decrementa r16, come¸ca com o valor 0x00
14 brne loop ; enquanto r16 > 0 fica decrementando r16, desvio para Atraso 15 dec r17 ; decrementa r17, come¸ca com o valor 0x00
16 brne loop ; enquanto r17 > 0 volta a decrementar r16 17
18 pop SREG ; Restaura o valor de SREG da pilha 19
20 ret ; retorno da sub-rotina
Rotinas Simples de Atraso
Contagem do n´ umero de ciclos:
1ciclo + 2ciclos ⇥255 +
1ciclo + 1ciclo =
<latexit sha1_base64="bSCGETZx2V3hXR0B54S4/gUx0EY=">AAADB3iclZHNahRBEMd7Jn7E0ZhNPHppXBRBWGYmLAomEPSSYwQ3CWwPS09P7abZ/hi6e3SXYR4gT+LRm3j1MXwbeyaLJpu9WNBQ/OpfXX+q8lJw6+L4dxBu3bv/4OH2o+jxk52nu729/TOrK8NgxLTQ5iKnFgRXMHLcCbgoDVCZCzjP5x/b+vkXMJZr9dktS8gknSk+5Yw6jya9bxEZRySHGVd1LqkzfNFEuItXOMHkPWacCY0J6egbT9O/1OKIgCr+NRLHJVicDode+Z/f3qBrvx5FJJv0+vEg7gLfTZJV0kerOJ3sBSek0KySoBwT1NpxEpcuq6lxfgZ4r5WFkrI5ncHYp4p651ndbbTBLz0p8FQb/5TDHb3ZUVNp7VLmXuldXtr1Wgs31caVm77Laq7KyoFi14OmlcBO4/Y8uOAGmBNLn1BmuPeK2SU1lDl/xI1TbsGSt349U/CVaSmp3yNhkpp5UxMHC1eTgqtZPUyaZk212KAatqrI7z5Z3/Td5CwdJAeD9FPaP/6wusI2eo5eoNcoQW/RMTpBp2iEWLATHASHwVF4FX4Pf4Q/r6VhsOp5hm5F+OsPRE7rlw==</latexit>
2 66 4
767ciclos
+ 1ciclo + 2ciclos
3 77 5⇥255 +
2 66 4
767ciclos
+ 1ciclo + 1ciclo
3 77
5= 197119ciclos
<latexit sha1_base64="cvDjY5DPZDlHYsqYkRzMVLizA6s=">AAADTnicrVLPb9MwFHayASX86uDIxaICIU2q4kylTBPSBJcdh7Ruk+qocpzXzmrsRLYD7aKc4A/kyj/BkRsCp6u2ruuRJ0f69H2f33t+L0mRCWPD8Kfnb23fu/+g9TB49PjJ02ftneenJi81hwHPs1yfJ8xAJhQMrLAZnBcamEwyOEumnxr97AtoI3J1YucFxJJNlBgLzqyjRu1fAR0GNIGJUFUimdViVgd4EW9w/10f0wPMBc9ygykN3GmUXaeRawWvsNGKP6Cg0puk1AoJBke9Ht79jxVX2LWCH8h+n5D9m3wBjUftTtgNF4HvArIEHbSM49GOd0TTnJcSlOUZM2ZIwsLGFdPW5QT3rNJAwfiUTWDooGLukXG1WEyNXzsmxeNcu09ZvGBXb1RMGjOXiXO6ri/MutaQm7Rhacfv40qoorSg+FWhcZlhm+NmyzgVGrjN5g4wroXrFfMLphm37l/YWOUWWYimX8cp+MpzKZmbK+WS6WldUQszW9FUqEnVI3W95pptcPUaV+BmT9YnfRecRl2y140+R53Dj8sttNBL9Aq9RQT10SE6QsdogLh34l1637zv/g//t//H/3tl9b3lnRfoVmy1/gEr6f8o</latexit>