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.