O Stack e Subrotinas• Permitem reusar o código• Escreva e depure o código uma vez, use-o quantas vezes
for preciso• Uma Subrotina deve ser chamada• Uma Subrotina sempre retorna algo ao seu término• Pode ter sua codificação feita no futuro• Ajuda a manter a legibilidade e manutenção do código• Pode-se aninhar Subrotinas• Se for um procedimento, não retorna um valor• Se for uma função, então retorna um valor
Como Subrotinas são implementadas no ARM
• Salto para a Subrotina (Branch and Link) BL<cc> label <cc>: LR ← PC + 4
<cc>: PC ← PC + IR(offset)• Link Register: LR (R14)
Armazena o endereço da instrução após o BL
• Retorno da SubrotinaMOV<cc> PC, LR <cc>: PC ← LR
Exemplo de Subrotina@ Mostra o valor de R5 no display
mov r0, r5 ; R0 contém o valor e ...mov r1, #1 ; R1 o ponto decimal BL Display8Segment ; Mostra valor no display
...Display8Segment:
stmfd sp!,{r0-r2,lr} ; Salva registradores no Stack
ldr r2,=Digits ; Carrega R0 com a combinaçãoldr r0,[r2,r0,lsl#2] ; de segmentos adequadatst r1,#0x01 ; Se r1=1,orrne r0,r0,#SEG_P ; então mostra pontoswi SWI_SETSEG8 ; Exibe valor no display
ldmfd sp!,{r0-r2,pc} ; Restaura registradores do Stack
O Stack• O stack é usado para “lembrar” valores• Provê uma área de armazenamento temporário• Permite a implementação de Subrotinas do tipo função• R13 aponta para o topo do stack (Top Of Stack -TOS)• R13 também é conhecido como Stack Pointer (SP)• Um Stack obedece a regra LIFO (last-in-first-out)• Último valor empilhado é o primeiro a ser desempilhado • O stack cresce “para baixo” na memória• Cada modo do proc. tem o seu stack pointer:• R13_fiq, R13_svc, R13_abt, R13_undef, . . .• R13 or SP se referem ao modo corrente
Operação do Stack
Operação do Stack
Operação do Stack
Operação do Stack
Operação do Stack
Operação do Stack
Operação do Stack
Operação do Stack
Operação do Stack
Operação do Stack
Operação do Stack
Operação do Stack
Stack como área temporária• Push: Salva registrador no stack
STR<cc> Rs, [SP], #-4 <cc>: MBR ← Rs <cc>: MAR ← SP
<cc>: M(MAR) ← MBR <cc>: SP ← SP - 4
• Pop: Recupera registrador do stackLDR<cc> Rd, [SP, #4]! <cc>: SP ← SP + 4<cc>: MAR ← SP<cc>: MBR ← M(MAR)<cc>: Rd ← MBR
Push/Pop de múltiplos registradores• Push: Salva um conjunto de registradores no Stack
STM<cc><mode> SP!, { <Register List> }• Pop: Recupera um conjunto de registradores
LDM<cc><mode> SP!, { <Register List> }• <mode> pode ser:– IB: Increment Before– IA: Increment After– DB: Decrement Before– DA: Decrement After
• <Register List>: Lista de registradores a serem armazenadosEx:, R0-R7, R10
Push/Pop de múltiplos registradoresPara facilitar o uso, o <mode> das instruções STM e LDM possuem apelidos que refletem o uso do stack:
• FD = Full Descending : STMFD/LDMFD = STMDB/LDMIA
• ED = Empty Descending : STMED/LDMED = STMDA/LDMIB
• FA = Full Ascending : STMFA/LDMFA = STMIB/LDMDA
• EA = Empty Ascending : STMEA/LDMEA = STMIA/LDMDB
• Qualquer stack que não seja o FD é raro!
Exemplo de Full Descending (FD)
Exercícios1. Criar uma Subrotina que retorne em R0 o número de caracteres (tamanho) de uma string. A string deverá ser terminada com o caracter 0x00. R0 deverá apontar para o início da string. R0 também deverá retornar o número de caracteres da string, excluindo o caracter de terminação. @ Calcula o tamanho de string1
LDR R0, =String1BL TamStringCMP R0, #0BEQ StringVazia
Exercícios2. Criar uma Subrotina para copiar parte de uma string (string1) em uma outra string (string2). Ambas as strings deverão ser terminadas com o caracter 0x00. R0 deverá apontar para o início de string1, R1 para o início de string2, R2 deverá conter a posição do primeiro caracter a ser copiado e R3 deverá conter o número (máximo) de caracteres a ser copiado.@ Copiar 8 caracteres de string1 em string2 começando @ pelo segundo caracter
LDR R0, =String1LDR R1,= String2MOV R2,#2MOV R3, #8BL CopiaSubstring
Exercícios3. Criar uma Subrotina que procure a primeira ocorrência de uma string (string1) dentro de outra string (string2). As strings deverão ser terminadas com o caracter 0x00. R0 deverá apontar para o início de string1 e R1 para o início de string2. R0 deverá retornar a posição em que string1 foi encontrada em string2 ou 0 caso não seja encontrada. @ Procurar string1 em string2
LDR R0, =String1LDR R1,= String2BL ProcuraSubstringCMP R0, #0BEQ NaoEncontrado