7. Instruções de ramificação

Estas fazem com que a execução salte para um local de destino normalmente especificado por uma etiqueta (ver a diretiva assembladora label()). As ramificações condicionais e as instruções it e ite testam os flags N (negativo), Z (zero), C (transporte) e V (overflow) do Registo de Estado do Programa de Aplicação (APSR) para determinar se a ramificação deve ser executada.

A maioria das instruções assembladoras expostas (incluindo operações de movimentação) define os flags, mas existem instruções de comparação explícitas para permitir testar valores.

Mais detalhes sobre o significado dos flags de condição são fornecidos na secção instruções de comparação.

7.1. Convenções do documento

Notação: Rm denota registos ARM R0-R15. LABEL denota uma etiqueta definida com a diretiva assembladora label(). <condition> indica um dos seguintes especificadores de condição:

  • eq Igual a (resultado foi zero)

  • ne Não igual

  • cs Transporte definido

  • cc Transporte 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. Ramificar para etiqueta

  • b(LABEL) Ramificação incondicional

  • beq(LABEL) ramificar se igual

  • bne(LABEL) ramificar se não igual

  • bge(LABEL) ramificar se maior ou igual

  • bgt(LABEL) ramificar se maior que

  • blt(LABEL) ramificar se menor que (<) (com sinal)

  • ble(LABEL) ramificar se menor ou igual a (<=) (com sinal)

  • bcs(LABEL) ramificar se o flag de transporte estiver definido

  • bcc(LABEL) ramificar se o flag de transporte estiver limpo

  • bmi(LABEL) ramificar se negativo

  • bpl(LABEL) ramificar se positivo

  • bvs(LABEL) ramificar se o flag de overflow estiver definido

  • bvc(LABEL) ramificar se o flag de overflow estiver limpo

  • bhi(LABEL) ramificar se maior (sem sinal)

  • bls(LABEL) ramificar se menor ou igual (sem sinal)

7.3. Ramificações longas

O código produzido pelas instruções de ramificação listadas acima utiliza uma largura de bits fixa para especificar o destino da ramificação, que é relativo ao PC. Consequentemente, em programas longos onde a instrução de ramificação está distante do seu destino, o assemblador produzirá um erro «branch not in range». Isto pode ser ultrapassado com as variantes «wide» (largas) como

  • beq_w(LABEL) ramificação longa se igual

As ramificações largas utilizam 4 bytes para codificar a instrução (em comparação com 2 bytes para as instruções de ramificação normais).

7.4. Subrotinas (funções)

Ao entrar numa subrotina, o processador armazena o endereço de retorno no registo r14, também conhecido como registo de ligação (lr). O retorno para a instrução após a chamada de subrotina é realizado através da atualização do contador de programa (r15 ou pc) a partir do registo de ligação. Este processo é tratado pelas seguintes instruções.

  • bl(LABEL)

Transfere a execução para a instrução após LABEL, armazenando o endereço de retorno no registo de ligação (r14).

  • bx(Rm) Ramifica para o endereço especificado por Rm.

Tipicamente, bx(lr) é emitido para retornar de uma subrotina. Para subrotinas encadeadas, o registo de ligação dos âmbitos exteriores deve ser guardado (normalmente na pilha) antes de realizar chamadas a subrotinas internas.