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.