Principais instruções e modos de endereçamento dos processadores ARM
MC404 1o semestre de 2015


Atualizado em 12 jun 2015 - Prof. Célio
  1. Modos de endereçamento para instruções operando sobre registradores

    Operandos imediatos para carga de registradores:
    MOV Rd, #constante-8-bits (ou que pode ser obtida via deslocamento de constante de 8 bits).
            Por exemplo: MOV Rd, #-1 é permitido, move ffffffff para  Rd 
    MVN Rd, #constante    - Mov negativo: Rd:= not constante
    LDR Rd, =constante-grande  (tipicamente um endereço na área de dados)
    
    Instruções lógico-aritméticas mais comuns (podem usar 2 ou 3 registradores):
       Obs: O sufixo s nessas instruções atualiza os flags na palavra de estado do processador.
    ADD   Rd, Rn                - Rd:= Rd + Rn
    ADD Rd, Rn, Rm              - Rd:= Rn + Rm (rn e Rm não mudam)
    ADD Rd, #const-8-bits       - Rd:= Rd + constante
    ADC   idem     - faz a soma adicionando também o bit C
    SUB   idem     - subtração
    RSB   idem     -  subtração reversa - exemplo:   RSB Rd, #0xff  Rd := 0xff - Rd  
    AND   idem     - "e"
    ORR   idem     - "ou"
    EOR   idem     - "ou exclusivo"
    MUL   idem  ex: MUL R0, R1  ou MUl R0, R1, R2 (R0:= R1 x R2)
    UMULL Rdlo, Rdh, Rn, Rm  - unsigned multiply, 64 bit result: (Rdlo, Rdh):= Rn x Rm
    MLA   Rd, Rm, Rs,Ra - multiply and accumulate: Rd :=  (Rm x Rs) + Ra
          Exemplo: MLA R0, R1, R2, R0  - R0 := R0 + (R1 x R2)
    UDIV  Rd, Rn, Rm - unsigned divide  ex: UDIV Rd, Rm  - Rd := Rd/Rm divisão inteira
    BIC   bit clear- ex: BIC  Rd, #(1<<24) zera o bit 24 de Rd ou: BIC Rd, Rd,Rn (Rd:=Rd AND not Rn)
    BFC   bit field clear - exemplo: BFC Rd, #4, #8  zera 8 bits de Rd a partir do bit 4
    BFI   bit field insert - exemplo BFI Rd, Rn, #4, #8  insere 8 bits menos sign de Rn a partir do bit 4 de Rd
    
    Instruções lógico-aritméticas com deslocamento (via "barrel shifter"):
    MOV, ADD, SUB, AND, ORR, EOR podem usar os deslocamentos LSL, LSR, ARS, ROR como no exemplo
    ADD Rd, Rn, LSL #8  -  Rd:= Rd + (Rn << #8)
    MOV Rd, Rn, LSL #8  -  Rd:= (Rn << 8) Rn não se altera 
    Um sinônimo para a instrução acima seria:
    LSL Rd, Rn, #8 (Logical Shift Left) - Rd:= Rn << 8
    LSL Rd, #8   - em vez de LSL poderíamos usar:
    LSR (Logical Shift Right)
    ARS (Arithmetic Shift Right)
    ROR (ROtate Right)    
    Mais exemplos:
    ---------------------------------------------------------------------------------------------------------
        MOV R0, 0x100            - R0:= 0x100
        MOV R0, R1                - R0:= R1
        MOV R0, R1, LSL 2        - R0:= R1*4, R1 não muda
        MOV R0, R1, LSL R2        - R0:= R1 deslocado à esquerda pelo valor nos 5 bits
                                  - menos signifs de R2. R1 e R2 não mudam.
                                  - em vez de LSL pode ser: LSR, ASR, ROR
                                  - o número de bits deslocados pode ser qualquer valor entre 0 e 31
        ADD R0, R1, 0x100        - R0:= R1 + 0x100  R1 não muda
        ADD R0, R1, R2            - R0:= R1+R2   R1 e R2 não mudam
        ADD R0, R1, R2, LSL 2    - R0:= R1+ R2*4, R1 e R2 não mudam
        ADD R0, R1, R2, LSL R3    - Thumb2 não suporta! R0:= R1 + R2 deslocado à esquerda pelo valor nos 5 bits
                                  - menos signifs de R3. R1, R2 e R3 não mudam.
                                  - em vez de LSL poderia ser: LSR, ASR, ROR
    Um exemplo interessante: multiplicar R0 por 10:
        ADD R0, R0, R0            - R0:= 2*R0
        ADD R0, R0, R0, LSL #2    - R0:= R0 + (R0*4)= 2*R0 original + (2*R0 original*4)= 10*R0 original
    ---------------------------------------------------------------------------------------------------------
    Endereçamento "pos-indexado":
    LDR R0, [R1], #4               - endereço do operando= (R1), R1:= R1 + 4    
    LDRB R0, [R1], #1              - endereço do operando= (R1), R1:= R1 + 1    
    LDR R0, [R1], R2               - endereço do operando= (R1), R1:= R1 + R2,  R2 não muda
    LDR R0, [R1], R2, LSL #2       - Thumb2 não suporta! endereço do operando= (R1), R1:= R1+ R2*4, R2 não muda
    ----------------------------------------------------------------------------------------------------
    Endereçamento "pre-indexado":
    LDR R0, [R1, #4]               - endereço do operando= (R1 + 4) , R1 não muda
    LDR R0, [R1, #4]!              - endereço do operando= (R1 + 4) , R1:= (R1 + 4)
    LDRB R0, [R1, #1]!             - endereço do operando= (R1 + 1) , R1:= (R1 + 1)
    LDR R0, [R1, R2]               - endereço do operando= (R1 + R2), R1 e R2 não mudam!
    LDR R0, [R1, R2]!              - Thumb2 não suporta! endereço do operando= (R1 + R2), R1:= R1+R2,  R2 não muda
    LDR R0, [R1, R2, LSL #2]       - endereço do operando= (R1 + R2*4), R1 e R2 não mudam!
    LDR R0, [R1, R2, LSL #2]!      - Thumb2 não suporta! endereço do operando= (R1 + R2*4),  R1:= R1+ R2*4, R2 não muda
    ---------------------------------------------------------------------------------------------- 
    
  2. Instruções de desvio condicional e incondicional As instruções de desvio condicional "consultam" os flags do registrador de estado (C, Z, N, V) e que devem ter sido atualizados numa instrução prévia (típicamente cmp ou uma instrução lógico-aritmética com o sufixo S). Esta "consulta" é uma expressão booleana envolvendo os flags, resultando na condição necessária para que o desvio ocorra: B rotulo - desvio incondicional para a instrução cujo endereço corresponde a "rotulo" BEQ rotulo - desvia para rotulo se zero BNE rotulo - desvia se diferente de zero BHI rotulo - desvia se "maior em valor absoluto" BHS/BCS rotulo - desvia se "maior ou igual em valor absoluto" ou se C=1 BLO/BCC rotulo - desvia se "menor em valor absoluto" ou se C=0 BLS rotulo - desvia se "menor ou igual em valor absoluto" BGE rotulo - desvia se "maior ou igual com sinal" BGT rotulo - desvia se "maior com sinal" BLE rotulo - desvia se "menor ou igual com sinal" BLT rotulo - desvia se "menor com sinal" BMI rotulo - desvia se negativo BPL rotulo - desvia se positivo ou zero BVS rotulo - desvia se overflow (V=1) BVC rotulo - desvia se não houve overflow (V=0) CBZ Rn, rotulo - compara Rn com zero e desvia para rotulo se Rn for zero; não altera flags CBNZ Rn, rotulo - compara Rn com zero e desvia se Rn for diferente de zero; não altera flags - limitaçãO: CBZ e CBNZ só podem desviar para frente! BL rotulo - chamada de subrotina: LR:PC+4, PC := endereço-associado-ao-rotulo BLX Rn - chamada de subrotina via registrador: LR:= PC+4, PC:= Rn BX Rn - desvia para endereço contido em Rn (PC:= Rn)
  3. Instruções para operações sobre pilha PUSH {reglist} - empilha a lista de registradores entre { }, separados por "," ou via intervalo "-" Exemplos: PUSH {r0-r4,LR}, PUSH {r1, r3, r5, r11, r12} POP {reglist} - desempilha a lista de registradores entre { }, separados por "," ou via intervalo "-" A ordem dos registradores em reglist deve ser a mesma da colocada na instrução prévia PUSH. Exemplos: POP {r0-r4, PC} POP {r1, r3, r5, r11, r12} PUSH e POP são casos particulares das instruções STM e LDM (p. 67-69 do manual).
  4. Você pode ver o detalhamento de qualquer instrução do ARM digitando no google: "ARM mnemonico instruction", por exemplo "ARM BFI instruction"