7. Instruções de desvio#
Estas fazem a execução saltar para um local de destino, normalmente especificado por um rótulo (veja a diretiva de assembler label()). Os desvios condicionais e as instruções it e ite testam os flags N (negativo), Z (zero), C (carry) e V (overflow) do Application Program Status Register (APSR) para determinar se o desvio deve ser executado.
A maioria das instruções de assembler expostas (incluindo as operações de move) define os flags, mas há instruções explícitas de comparação para permitir que valores sejam testados.
Mais detalhes sobre o significado dos flags de condição são fornecidos na seção instruções de comparação.
7.1. Convenções do documento#
Notação: Rm denota os registradores ARM R0-R15. LABEL denota um rótulo definido com a diretiva de assembler label(). <condition> indica um dos seguintes especificadores de condição:
eq Igual a (resultado foi zero)
ne Diferente
cs Carry definido
cc Carry limpo
mi Menos (negativo)
pl Mais (positivo)
vs Overflow definido
vc Overflow limpo
hi > (comparação sem sinal)
ls <= (comparação sem sinal)
ge >= (comparação com sinal)
lt < (comparação com sinal)
gt > (comparação com sinal)
le <= (comparação com sinal)
7.2. Desvio para rótulo#
b(LABEL) Desvio incondicional
beq(LABEL) desvia se igual
bne(LABEL) desvia se diferente
bge(LABEL) desvia se maior que ou igual
bgt(LABEL) desvia se maior que
blt(LABEL) desvia se menor que (<) (com sinal)
ble(LABEL) desvia se menor que ou igual a (<=) (com sinal)
bcs(LABEL) desvia se o flag de carry estiver definido
bcc(LABEL) desvia se o flag de carry estiver limpo
bmi(LABEL) desvia se negativo
bpl(LABEL) desvia se positivo
bvs(LABEL) desvia se o flag de overflow estiver definido
bvc(LABEL) desvia se o flag de overflow estiver limpo
bhi(LABEL) desvia se maior (sem sinal)
bls(LABEL) desvia se menor ou igual (sem sinal)
7.3. Desvios longos#
O código produzido pelas instruções de desvio listadas acima usa uma largura de bits fixa para especificar o destino do desvio, que é relativo ao PC. Consequentemente, em programas longos onde a instrução de desvio está distante de seu destino, o assembler produzirá um erro “branch not in range”. Isso pode ser superado com as variantes “wide”, como
beq_w(LABEL) desvio longo se igual
Os desvios wide usam 4 bytes para codificar a instrução (em comparação com 2 bytes para as instruções de desvio padrão).
7.4. Sub-rotinas (funções)#
Ao entrar em uma sub-rotina, o processador armazena o endereço de retorno no registrador r14, também conhecido como registrador de vínculo (lr). O retorno para a instrução após a chamada da sub-rotina é realizado atualizando o program counter (r15 ou pc) a partir do registrador de vínculo. Esse processo é tratado pelas instruções a seguir.
bl(LABEL)
Transfere a execução para a instrução após LABEL, armazenando o endereço de retorno no registrador de vínculo (r14).
bx(Rm) Desvia para o endereço especificado por Rm.
Normalmente bx(lr) é emitido para retornar de uma sub-rotina. Para sub-rotinas aninhadas, o registrador de vínculo dos escopos externos deve ser salvo (geralmente na pilha) antes de realizar chamadas de sub-rotinas internas.