AULA 5 - Microprocessadores - Graduação: mudanças entre as edições

De IFSC
Ir para navegação Ir para pesquisar
imported>Fargoud
imported>Fargoud
Sem resumo de edição
 
(48 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
=CONJUNTOS DE INSTRUÇÕES=
=CONJUNTOS DE INSTRUÇÕES GENÉRICAS DE MICROPROCESSADORES=


Um programador de linguagem de alto nível normalmente conhece muito pouco acerca da arquitetura da máquina que está usando.
Um programador de linguagem de alto nível normalmente conhece muito pouco acerca da arquitetura da máquina que está usando.
Linha 87: Linha 87:
====Exercício====
====Exercício====


Em uma [https://wiki.ifsc.edu.br/mediawiki/index.php/AULA_13_-_Eletr%C3%B4nica_Digital_1_-_Gradua%C3%A7%C3%A3o#Unidade_L.C3.B3gico-Aritm.C3.A9tica_.28ULA.29 ULA de inteiros de 4 bits], com formato de instrução '''''[OPCODE(5) A(4) B(4)]''''', qual seria a instrução correspondente, se a intenção fosse executar a operação lógica ''Y = OU(A', B) '', com ''A = 0001b'' e ''B = 1010''?
Em uma [https://wiki.ifsc.edu.br/mediawiki/index.php/AULA_13_-_Eletr%C3%B4nica_Digital_1_-_Gradua%C3%A7%C3%A3o#Unidade_L.C3.B3gico-Aritm.C3.A9tica_.28ULA.29 ULA de inteiros de 4 bits], com formato de instrução '''''[OPCODE(5) A(4) B(4)]''''', qual seria a instrução correspondente, se a intenção fosse executar a operação lógica ''Y = OR(A', B) '', com ''A = 0001b'' e ''B = 1010''?


==NÚMERO DE ENDEREÇOS==
==NÚMERO DE ENDEREÇOS==
Linha 202: Linha 202:
[[imagem: MIPconjp23.png|center]]
[[imagem: MIPconjp23.png|center]]


=CONJUNTO DE INSTRUÇÕES DO ARM=


O conjunto de instruções também é chamado de [https://en.wikipedia.org/wiki/Instruction_set_architecture '''"ISA - Instruction Set Architecture"'''].
[[imagem: MIPinstARM1.png|center]]
A arquitetura ARM trabalha com três tipos de instruções: o ARM, THUMB e o THUMB-2.
O conjunto THUMB de instruções de 16 bits trabalha com registradores de 32 bits.
O código THUMB é capaz de reduzir em até 65% o tamanho de um código ARM (maior densidade de código), e aumentar em até 160% o desempenho, em relação a um processador ARM equivalente, conectado a um sistema de 16 bits, apenas.
[[imagem: MIPinstARM4.png|center]]
==Características do ISA Arm==
* 13 registradores de propósito geral:
** R0 a R7 (low registers)
** R8 a R12 (high registers)
* 3 registradores de uso/significado especial
** r13: stack pointer (SP)
** r14: link (LR)
** r15: (PC)
* 1 registrador de propósito especial
** xPSR = Program Status Register
* Registradores xPSR, PC, LR, R12, R3, R2, R1 e R0 são armazenados automaticamente na pilha quando uma interrupção ocorre.
[[image: MIPregsARM.png|center]]
[[image: MIPregsARM2.png|center]]
* Arquitetura load-store: as instruções somente lidam com valores que estejam nos registradores (ou imediatos) e sempre armazenam resultados em algum registrador. O acesso à memória é feito apenas através das instruções '''load''' (para carregar o valor da memória em um registrador) e '''store''' (para armazenar o valor de um registrador na memória).
* Permite a execução condicional de várias instruções.
* Máquina de 3 endereços – dois registradores operandos e um registrador de resultado são especificados.
** 1º operando: especifica o local onde será armazenado o resultado da operação.
** Outros: valores imediatos ou locais onde se encontram os dados.
  Exemplo: ADD R1, R2, #4
  R1 ← (R2) + 4
* Uniformidade e tamanhos fixos dos campos das instruções para facilitar a decodificação.
* I/O mapeado em memória: a comunicação com dispositivos periféricos é feita no próprio espaço de endereçamento de memória (via load e store).
* Endereços de memória se referem a bytes individuais.
==Formato de instruções==
Apesar das diferenças entre as instruções, os projetistas mantiveram certa regularidade no formato delas, facilitando a decodificação. O formato geral é do bit menos significativo ao mais significativo, o seguinte:
* 4 bits para condição de execução;
* 3 bits para o tipo de instrução;
* 5 bits para o ''opcode'';
* 20 bits, cujo uso e repartição varia para acomodar endereços, referências a registradores,
deslocamentos e rotações.
'''Operandos:'''
Registradores:
ADD r1, r2, r3
MOV r1, r2
Imediatos: identificados pelo símbolo #
ADD r1, r2, #10
MOV r1, #0
Maiores detalhes sobre o formato das instruções podem ser vistos na figura.
[[imagem: MIPinstARM16.png|center]]
Estas condições são ativadas através de sufixos que são colocados junto com os minemônicos das instruções.
Por exemplo, um salto (B) pode ser acompanhado de um NE (not equal), o que gera uma expressão BNE.
Essa instrução só será executada caso a condição seja verdadeira.
==Conjunto de instruções ARM==
Quanto ao número de bits, as instruções podem ser dos seguintes tipos:
'''ARM'''
[[imagem: MIPinstARM5.png|center]]
'''THUMB'''
* Operações de 32 bits, em instruções de 16 bits
* Introduzido no processador [[media: arm7ds.pdf |ARM7TDMI (Datasheet)]]
* Suportado por todos os processadores ARM, desde então
'''THUMB-2'''
* Permite uma mistura com performance otimizada de instruções de 16/32 bits
* Todas as operações do processador podem ser realizadas no estado "Thumb"
* Suportado por todos os processadores da linha Cortex-M, desde então.
[[imagem: MIPinstARM12.png|center]]
Quanto ao tipo de operação, tipos de instruções oferecidos são:
* Load/Store: Instruções de carregamento e escrita de dados na memória. Podem ler/escrever
palavras inteiras(32 bits), meias-palavras(16 bits), bytes sem sinal, e podem ler e estender o
sinal de meias-palavras.
A arquitetura ARM suporta dois tipos de instruções de load e store que transferem o conteudo de um registrador para a memória ou ao contrário.
O primeiro tipo pode carregar ou escrever uma parava de 32 bits ou um byte sem sinal.
O segundo tipo pode ler ou escrever meia palavra de 16 bit sem sinal, e pode carregar e sinalizar meia palavra de 16 bit ou um byte. Este tipo de instrução está disponível apenas para a arquitetura ARM versão 4 ou posterior.
[[image: MIPloadst.png|center]]
* Load/Store em blocos: são instruções que permitem definir a leitura/escrita de blocos de até 16 registradores em uma única instrução. Isso é feito com uma máscara de 16 bits na instrução
que define quais registradores serão usados, e permite atingir uma banda de comunicação
quatro vezes maior do que uma instrução que usa um único registrador.
Essas instruções podem ser usadas para início e retorno de chamadas, assim como para ler blocos de memória.
* Desvio: Todos os processadores ARM suportam instruções de branch com saltos condicionais para frente ou para trás de até 32M. A condição é dada por um campo de 4 bits.  Saltos mais longos podem ser feitos através de chamadas de subrotinas como por exemplo o ''Branch whith Link (BL)'', que mantem o endereço de retorno no LR (R14).
* Processamento de Dados: são operações de adição e subtração, operações lógicas AND, OR e XOR, e instruções de comparação e teste;
** Multiplicação de inteiros: as multiplicações de inteiros podem ser feitas com operandos de 32 ou 16 bits, e o resultado pode ocupar 32 ou 64 bits;
** Adição/Subtração paralelas: essas instruções permitem aplicar a operação em partes dos operandos, de forma paralela.
Um exemplo é a instrução ADD16, que adiciona as primeiras meias-palavras dos operandos para formar a meia palavra superior do resultado, enquanto faz o mesmo com as meias-palavras inferiores para formar a parte inferior do resultado. Essas instruções são úteis para processamento de imagens
[[image: MIPinstrpd.png|center]]
[[image: MIPinstrpd2.png|center]]
* Extensão: são instruções para reagrupar dados;
* Acesso a registrador de estado: é permitido ler e escrever em partes do registrador de estados. Existem duas instruções para mover os conteúdos de um registrador de propósito geral e de um registrador de estado, que são as seguintes:
** MRS – move o conteúdo do registrador de estado para um registrador de propósito geral.
** MSR – move o conteúdo do registrador de propósito para um registrador de estado.
* Interface para coprocessadores: há um grupo de instruções para trocas de dados com coprocessadores, assim como para controle destes. Elas permitem ao processador ARM iniciar uma operação de processamento de um coprocessador. Permite fazer transferências entre os registradores do processador e dos coprocessadores. Permitem também o processador criar endereços para o coprocessador carregar e escrever instruções. Todo o tratamento de ponto flutuante é feito por um coprocessador, cuja presença nos chips é opcional.
* Intercâmbio com Thumb: são instruções para indicar se serão executadas instruções de 32 ou 16 bits. A instrução BX permite a troca entre o estado ARM e o estado THUMB. Esta instrução copia o conteúdo de um registrador de propósito geral para o PC. Caso o bit[0] do valor transferido para o PC seja 1, o processador troca para o estado THUMB.
* instruções geradoras de exceções. Existe duas instruções deste tipo:
**  a SWI que causa uma interrupção de software. É o mecanismo principal utilizado pelo ARM para poder executar códigos do Sistema Operacional no modo de usuário (User Mode).
** E existe o BKPT. Esta instrução é usada para breakpoints na arquitetura ARM da versão 5 em diante.
 
===Exemplo1:===
Programa calculadora simples 4 op
;PROGRAMA CALCULADORA DE 4 OPERAÇÕES
; R4 = 1 -> R3 = R2 + R1
; R4 = 2 -> R3 = R2 - R1
; R4 = 3 -> R3 = R2 X R1
; R4 = 4 -> R3 = R2 / R1
mov r4,#4 ; valor de R4 define operação
mov r2,#60
mov r1,#12
mov r3,#0
cmp r4,#1
blt fim
beq soma
;******
cmp r4,#2
beq subt  ; se r4=2 pula para subtração
;******
cmp r4,#3
beq mult
;******
cmp r4,#4
bgt fim
beq divisao
;******
;******; ALGORITMO DE SOMA:
soma add r3,r2,r1
    b fim
;******; ALGORITMO DE SUBTRAÇÃO:
subt sub r3,r2,r1
    b fim
;******; ALGORITMO DE MULTIPLICAÇÃO:
mult add r3, r3, r2
        sub r1, r1, #1
        cmp r1, #1
        bge mult
        b fim
;******; ALGORITMO DE DIVISÃO:
divisao mov r4,r2
div2 subge r4,r4, r1
                add r3, r3,#1
                cmp r4,r1
                bge div2
                b fim
fim
===Exemplo2:===
Programa em instruções ARM que implementa uma calculadora de 4 operações inteiras e grava os resultados em arquivo de saída (ARMSIM):
;************************
; programa CALCULADORA
; R3 = R2 op R1
;
;onde 'op':
; R4 = 1 - SOMA
; R4 = 2 - SUBTRACAO
; R4 = 3 - MULTIPLICACAO
; R4 = 4 - DIVISAO
;*************************
OutFileHandle: .word 0
InFileHandle: .word 0
InFileName:  .asciz "arqentrada.txt"
OutFileName: .asciz "ArqSaida.txt"
Saidasoma: .asciz "Soma = "
Saidasub:  .asciz "Subtracao = "
Saidamult: .asciz "Multiplicacao = "
Saidadiv1: .asciz "Divisao = "
Saidadiv2: .asciz "\n Resto = "
Saidafim:  .asciz "\n Fim do processamento! "
      ldr r0,=InFileName
      mov r1,#0
      swi 0x66
      swi 0x6c
;******
      mov r4,r0
      mov r2,#6
      mov r1,#2
      mov r3,#0
    cmp r4,#1
      blt fim
      beq soma
;******
      cmp r4,#2
      beq subt
;******
      cmp r4,#3
      beq mult
;******
      cmp r4,#4
      bgt fim
      beq divisao
;******
soma: add r3,r2,r1
      ldr r0,=Saidasoma
      swi 0x02
      add r0,r3,#'0
      swi 0x00
      b fim
subt: sub r3,r2,r1
      ldr r0,=Saidasub
      swi 0x02
      add r0,r3,#'0
      swi 0x00
      b fim
mult: mul r3,r2,r1
      ldr r0,=Saidasoma
      swi 0x02
      add r0,r3,#'0
      swi 0x00
      b fim
divisao:  mov r4,r2
div2:    subge r4,r4, r1
        add r3, r3,#1
        cmp r4,r1
        bge div2
        ldr r0,=Saidadiv1
        swi 0x02
        add r0,r3,#'0
        swi 0x00
        mov r0,#'\0
        swi 0x00
        ldr r0,=Saidadiv2
        swi 0x02
        add r0,r4,#'0
        swi 0x00
        b fim
fim: ldr r0, =Saidafim
    swi 0x02
===Exemplo 3:===
Programa que executa operações aritméticas e lógicas nos operandos
  mov r1,#4
  mov r2,#30
  mov r3,#1
  mov r4, #5
  ORR R1, R2, #0x20 ;R1 = R2 | 0x20
  ADD R3, R2, R4, LSL #3 ; R3 = R2 + (R4 << 3)
  RSB R5, R4, #0 ; R4 = 0 - R5
  SUB R1, R3, R2, LSR R4 ;R1 = R2 - (R3 >> R4)
===Exercícios:===
# Escreva o programa que implementa um loop com 40 iterações, incrementando uma variável do valor 0 a 39 e somando o valor 3, a cada iteração, ao valor inicial (=3) armazenado em R1.  [[Exemplo de solução 2]]
# Escreva o programa que implementa as operações lógicas (AND, OR, XOR, NXOR, NAND E NOR) entre dois valores, armazenados em R4 e R5. [[Exemplo de solução 3]]
# Implemente, no ARMSIM, o programa Arm que resolve a equação: Y = (A - B) / (C + D x E). Dica: armazene A em R0, B, em R1, C, em R2, D, em R3 e E, em R4. [[Exemplo de solução 4]]
# Implemente, no ARMSIM, o programa que lê compara os valores armazenados em R1, R2 e R3 e devolve o maior dentre eles em R4, e o menor, em R5. [[Exemplo de solução]]
==O CONJUNTO DE INSTRUÇÕES THUMB==
O THUMB possui instruções com as mesmas finalidades das instruções ARM, porém são codificadas com 16 bits.
Estas instruções THUMB geram códigos menores porém muitas vezes ocorre de aumentar o número de instruções que o processador deve executar.
Uma solução para isso são aplicações que utilizam ambos tipos de instruções (ARM e THUMB).
Aplicações deste tipo conseguem reduzir o tamanho do seu código significativamente e conseguem manter o consumo de energia baixo.
Algumas instruções THUMB são:
===ASR, LSL, LSR, ROR e RRX - Instruções de deslocamento===
As instruções a seguir são, na verdade, sinônimos para a instrução
''MOV Rd, Rm, XXX #n ''
onde XXX é um dentre LSR, LSL, ASR, ROR e n é uma constante variando de 0-31.
'''Obs''': se o sufixo S for acrecentado a XXX então o último bit deslocado de Rd entra no bit C (Carry) da palavra de estado.
'''Obs''': os bits de uma palavra são numerados de 0 a 31, do menos significativo ao mais significativo
====Sintaxe:====
''op{S}{cond} Rd, Rm, Rs''
''op{S}{cond} Rd, Rm, #n''
''RRX{S}{cond} Rd, Rm''
onde:
*''op'' is one of:
** ASR: Deslocamento à direita aritmético
** LSL: Deslocamento à esquerda lógico
** LSR: Deslocamento à direita lógico
** ROR: Rotaciona à direita
*''S'' é um sufixo opcional. Se S for especificado, as flags condicionais são atualizadas no resultado da operação.
*''Rd'' é o registrador destino
*''Rm'' é o registrador contendo o valor a ser deslocado
*''Rs'' é o registrador contendo o comprimento de deslocamento a ser aplicado ao valor em Rm. Apenas o byte menos significativo é usado e deve variar entre [0,255].
*''n'' é o comprimento de deslocamento. Depende da instrução:
** ASR: comprimento de deslocamento de 1 a 32
** LSL: comprimento de deslocamento de 0 a 31
** LSR:  comprimento de deslocamento de 1 a 32
** ROR:  comprimento de deslocamento de 1 a 31
LSR Rd, #n  - desloca Rd n bits para a direita inserindo n 0s à esquerda (divide Rd por 2**n)
LSL Rd, #n  - desloca Rd n bits para a esquerda inserindo n 0s à direita (multiplica Rd por 2**n)
ASR Rd, #n  - desloca Rd n bits para a direita, replicando o bit 31 (preserva o bit de sinal)
                    - divide um inteiro com sinal por 2**n
ROR Rd, #n  - rotaciona para a direita n bits de Rd (o bit 0, - significativo, entra no lugar do bit 31)
XXX Rd, Rm,#n - variante permitida das instruções acima; Rm não muda
RRX Rd, Rm  - rotaciona um bit do par (Rm,C) como se fosse uma palavra de 33 bits:  Rd0->C, C->Rd31, etc
                    - resultado vai para Rd, Rm não é alterado, exceto se Rd=Rm.
====Operação====
ASR, LSL, LSR e ROR movem os bits no registrador Rm para a esquerda ou para a direita, pelo número de lugares especificado pela constante n, ou registrador Rs.
RRX move os bits no registrador Rm para a direita 1 vez.
Em todas estas instruções, o resultado é escrito para Rd, mas o valor em Rm continua inalterado.
====Restrições====
Não use com SP ou PC.
====Flags de condição====
Se S for especificado:
* estas instruções atualizam as flags N e Z de acordo com o resultado
* a flag C é atualizada com o último bit deslocado, exceto quando o comprimento do deslocamento é 0.
====Exemplos:====
ASR R7, R8, #9; arithmetic shift right by 9 bits
LSLS R1, R2, #3; logical shift left by 3 bits with flag update
LSR R4, R5, #6; logical shift right by 6 bits
ROR R4, R5, R6; rotate right by the value in the bottom byte of R6
RRX R4, R5; rotate right with extend
===BFC - Bit field clear e BFI - Bit field insert===
====Sintaxe====
''BFC{cond} Rd, #lsb, #width''
''BFI{cond} Rd, Rn, #lsb, #width''
onde:
* ''cond'' é o código condicional, cc.
* ''Rd'' é o registrador destino.
* ''Rn'' é o registrador fonte.
* ''lsb'' é a posição do bit menos significativo no campo de bits [0-31].
* ''width'' é a largura do campo de bits [1-32].
====Operação====
BFC zera um campo de bits em um registrador. Limpa ''width'' bits em ''Rd'', iniciando da posição inferior ''lsb''.
Os demais bits permanecem inalterados.
BFI copia um campo de bits de um registrador para outro. Substitui ''width'' bits em ''Rd'', iniciando da posição inferior ''lsb'', pelos ''width'' bits em ''Rn'', iniciando da posição bit[0]. Os demais bits permanecem inalterados.
====Restrições====
Não é permitido utilizar os registradores SP e PC com estas instruções.
Estas instruções não afetam as flags.
====Exemplos:====
BFC R4, #8, #12 ; Limpa o bit 8 até bit 19 (12 bits) de R4
BFI R9, R2, #8, #12 ; Substitui bits 8 a 19 (12 bits) de R9 com bits 0 a 11 de R2
===AND, ORR, EOR, BIC, and ORN===
E, OU, OU EXCLUSIVO, Zera bit, E NÃO-OU lógicos.
====Sintaxe====
''op{S}{cond} {Rd,} Rn, Operand2''
onde:
* ''op'' é uma das operações:
** AND: E lógico
** ORR: OU lógico ou seta-bit
** EOR: OU exclusivo lógico
** BIC: NÃO-E lógico ou zera bit
** ORN: NÃO-OU lógico
*''S'' é o sufixo opcional. Se S for especificado, as flags de código condicional serão atualizadas como resultado da operação.
*''cond'' é o código de condição opcional
*''Rd'' é o registrador destino
*''Rn'' é o registrador que contém o primeiro operando
*''Operand2'' é o segundo operando
====Operação====
As instruções AND, EOR, e ORR realizam operações E, OU-EXC e OR bit-a-bit nos valores de Rn e operand2.
A instrução BIC realiza uma operação E nos bits de Rn com o complemento dos correspondentes bits no valor de operand2.
A instrução ORN realiza uma operação OU nos bits de Rn com o complemento dos bits correspondentes no valor de operand2.
====Restrições====
Não usar em SP e PC.
====Flags de condição====
Se S for especificado, estas instruções:
* Atualizam as flags N e Z de acordo com o resultado.
* Podem atualizar a flag C durante o cálculo de operand2
* Não afetam a flag V
====Exemplos====
AND R9, R2,#0xFF00
ORREQ R2, R0, R5
ANDS R9, R8, #0x19
EORS R7, R11, #0x18181818
BIC R0, R1, #0xab
ORN R7, R11, R14, ROR #4
ORNS R7, R11, R14, ASR #32
===ADD, ADC, SUB, SBC, and RSB===
Soma, soma com carry, subtrai, subtrai com carry e subtrai reverso.
====Sintaxe====
''op{S}{cond} {Rd,} Rn, Operand2''
''op{cond} {Rd,} Rn, #imm12; ADD and SUB only''
onde:
*''op'' é:
** ADD: Soma
** ADC: Soma com carry
** SUB: Subtração
** SBC: Subtração com carry
** RSB: Subtração reversa
*''S'' é o sufixo opcional. Se S for especificado, as flags serão atualizadas no final da operação.
*''cond'' é o cc
*''Rd'' é o registrador destino. Se for omitido, o destino é o próprio '''Rn'''.
*''Rn'' é o registrador contendo o primeiro operando
*''Operand2'' é o segundo operando flexível
*''imm12'' é qualquer valor na faixa de 0-4095 
====Operação====
A instrução ADD adiciona o valor do operand2, ou imm12, ao valor de Rn.
A instrução ADC adiciona o valor do Rn e operand2, junto com a flag de carry.
A instrução SUB subtrai o valor de operand2 do valor em Rn. Se a flag de carry estiver zerada, o resultado é diminuído de um.
A instrução SBC subtrai o valor em Rn de operand2. Esta instrução é útil porque operand2 permite uma faixa maior de valores.
A instrução RSB subtrai o valor do operand2, ou imm12, ao valor de Rn.
A instrução ADDW é equivalente à instrução ADD, que usa o operando imm12. SUBW é equivalente à instrução SUB, que usa o operando imm12.
===CBZ and CBNZ===
Compara e desviam se zero; compara e desvia se não-zero.
====Sintaxe:====
''CBZ Rn, label''
''CBNZ Rn, label''
onde:
*''Rn'' é o registrador contendo o operando.
*''label'' é o destino do desvio.
====Operação====
Use as instruções CBZ e CBNZ para evitar mudar as flags de cc e reduzir o número de instruções
A instrução ''CBZ Rn, label'' não altera as flags de condição, mas, ao contrário, é equivalente a:
CMP Rn, #0
BEQ label
A instrução ''CBNZ Rn, label'' não altera as flags de condição, mas, ao contrário, é equivalente a:
CMP Rn, #0
BNE label
====Restrições====
* Rn deve ser R0 a R7
* O destino do desvio deve estar entre 4 e até 130 bytes após a instrução
* Estas instruções não podem ser usadas dentro de um bloco IT.
====Flags de condição====
Não alteram as flags
====Exemplos====
CBZ R5, target ; Forward branch if R5 is zero
CBNZ R0, target ; Forward branch if R0 is not zero
===CMP and CMN===
Compara e compara negativo.
====Sintaxe:====
''CMP{cond} Rn, Operand2''
''CMN{cond} Rn, Operand2''
onde:
* ''cond'' é um código de condição opcional (c.c.)
* ''Rn'' é o registrador do primeiro operando
* ''Operand2'' é o segundo operando
====Operação====
As instruções comparam o valor do registrador com operand2.
Elas atualizam a condição da flag no resultado, mas não escrevem o resultado em um registrador.
A instrução CMP subtrai o valor de operand2 do valor em Rn. Faz o mesmo que a instrução SUBS, exceto que o resultado é descartado.
A instrução CMN adiciona o valor de operand2 ao valor em Rn. Faz o mesmo que a instrução ADDS, exceto que o resultado é descartado.
====Restrições====
Não é permitido usar PC e operand2 não pode ser SP.
====Flags de condição====
As instruções atualizam as flags N, Z, C e V, de acordo com o resultado.
====Exemplos:====
CMP R2, R9
CMN R0, #6400
CMPGTSP, R7, LSL #2
===CLZ - Count leading zeros===
====Sintaxe:====
'''CLZ{cond} Rd, Rm'''
onde:
* ''cond'' é o cc opcional.
* ''Rd'' é o registrador destino
* ''Rm'' é registrador operando
====Operação====
A instrução CLZ conta o número de zeros no valor em Rm e retorna o resultado em Rd.
O valor resultante é 32 se nenhum bit está setado no registrador fonte, e zero, se bit[31] é setado.
====Restrições====
Não use com SP e PC.
====Flags de condição====
Esta instrução não altera as flags.
====Exemplos====
CLZ R4,R9
CLZNE R2,R3
=== IT - If-Then condition instruction===
====Sintaxe:====
''IT{x{y{z}}} cond''
onde:
*''x'' especifica a condição chave para a segunda instrução no bloco IT.
*''y'' especifica a condição chave para a terceira instrução no bloco IT. 
*''z'' especifica a condição chave para a quarta instrução no bloco IT.
*''cond'' especifica a condição chave para a primeira instrução no bloco IT. 
As condições chave para segunda, terceira e quarta instruções do bloco podem ser:
*T: Then - Então. Aplica a condição ''cond'' à instrução.
* E: Else - Senão. aplica a condição inversa de ''cond'' à instrução.
Exemplo:
[[image: MIPinstit1.png|center]]
[[image: MIPinstit2.png|center]]
====Operação====
A instrução IT realiza um das quatro instruções condicionais seguintes.
As condições podem ser as mesmas, ou algumas podem ser o inverso lógico das outras. As instruções que seguem a instrução IT formam o "bloco IT".
As instruções no bloco IT, incluindo os branches, devem especificar a condição {cond} como parte de suas sintaxes.
Podem ser geradas exceções nos blocos IT.
====Restrições====
As seguintes instruções não são permitidas num bloco IT:
* IT
* CBZ e CBNZ
* CPSID e CPSIE.
Um branch ou qualquer outra instrução que modifique o PC deve estar fora de um bloco IT, ou deve ser a última instrução dentro do bloco IT. São:
* ADD PC, PC, Rm
* MOV PC, Rm
* B, BL, BX, BLX
* qualquer instrução LDM, LDR, ou POP que escreva no PC
* TBB e TBH
Não desvie para qualquer instrução INTERNA a um bloco IT, exceto quando retornando de um Exception Handler.
Para restrições adicionais, consulte o manual do seu Arm Assembler.
====Flags de condição====
Esta instrução não altera as flags.
====Exemplos:====
ITTE NE ; Proximas 3 instruções são condicionais
ANDNE R0, R0, R1 ; ANDNE não atualiza as flags de condicao
ADDSNE R2, R2, #1 ; ADDSNE atualiza as flags de condicao
MOVEQ R2, R3 ; Move Conditional
CMP R0, #9 ; Converte valor hexa R0 (0 a 15) para ASCII
; ('0'-'9', 'A'-'F')
ITE GT ; Proximas 2 instrucoes sao condicionais
ADDGT R1, R0, #55 ; Converte 0xA -> 'A'
ADDLE R1, R0, #48 ; Converte 0x0 -> '0'
IT GT ; bloco IT com apenas uma instrucao condicional
ADDGT R1, R1, #1 ; Incrementa R1 condicionalmente
ITTEE EQ ; Proximas 4 instrucoes são condicionais
MOVEQ R0, R1 ; move Condicional
ADDEQ R2, R2, #10 ; add Condicional
ANDNE R3, R3, #1 ; AND Condicional
BNE.W dloop ; Instrucao Branch instruction apenas pode ser usada no final
; de um bloco IT
IT NE ; proxima instrucao é condicional
ADD R0, R0, R1 ; erro de sintaxe: nenhum codigo condicional
===Execução condicional de instruções===
As instruções lógico-aritméticas podem ser condicionalmente executadas dependendo dos flags da palavra de estado que foram atualizados numa instrução anterior (usualmente imediatamente anterior).
Existem 15 condições que podem ser usadas como sufixo da instrução, e que são as mesmas usadas nas instruções de salto condicional:
eq, ne, cs ou hs, cc ou lo, mi, pl, vs, vc, hi, ls, ge, lt, gt, le, al.
Para que a execução condicional seja possível até 4 instruções devem ser precedidas pela instrução especial "If-Then condition instruction":
  it cond,
onde cond é uma das 15 siglas de 2 letrasi citadas anteriormente (existem outros 3 possíveis parâmetros).
Exemplos:
(1) suponha que r1 contem um inteiro com sinal: colocar em r0 o valor absoluto desse inteiro:
movs r0, r1 @ atualiza flags
it mi @ queremos tomar o negativo caso r0 <0
rsbmi r0, #0    @ faça r0 := 0 - r0 caso o bit N estivesse ligado
Obs: o mesmo código em instruções ARM seria:
mov r0, #12
mov r1, #8
mov r2, #4
loop:  cmp  r1, r2        @ cmp sempre atualiza flags
@ queremos testar se r1 > r2
subgt  r1, r1 ,r2    @ se r1 > r2, faça r1:=r1-r2     
sublt  r2, r2 ,r1    @ se r1 < r2 faça  r2:= r2-r1
bne  loop            @ se r1 # r2 volte ao laço
(2) algoritmo para calcular o máximo divisor comum de dois inteiros em r1 e r2, devolvendo o resultado em r1 e r2:
loop:  cmp  r1, r2        @ cmp sempre atualiza flags
  it gt              @ queremos testar se r1 > r2
  subgt r1, r2        @ se r1 > r2, faça r1:=r1-r2
  it lt              @ senão teste por <
  sublt  r2, r1      @ se r1 < r2 faça  r2:= r2 -r1
  bne  loop          @ se r1 # r2 volte ao laço
    @ senão mdc=r1=r2
-------------------
Outras instruções THUMB:
* RBIT - Reverse bits - p-81
* REV - Reverse byte order in a word - p-81 (passa uma palavre de "little endian" para "big endian" e vice-versa)
* SXTB - Sign extend a byte - p-90
* TBB - Table branch byte - p-96
* UDIV - Unsigned divide - p-86
* UMULL - Unsigned multiply (32x32), 64 bit result
* UXTB - Zero extend a byte - p-90
* CPSID/CPSIE - Interrupts Disable/Enable - p-98
Maiores informações: [[media: MIPciCM3.pdf| The Cortex-M3 instruction set]]
==Conjunto de instruções THUMB2==
Tradicionalmente todas as instru&ccedil;&otilde;es da arquitetura
ARM tem tamanho regular de 32 bits (4 bytes)
Na gera&ccedil;&atilde;o 4 de processadores ARM (Tipo ARM7-TDMI) foi incuido o conjunto
de instru&ccedil;&otilde;es alternativo THUMB em que a maioria das instru&ccedil;&otilde;es tem 2 bytes.
Nos processadores ARM7-TDMI os conjuntos de instru&ccedil;&otilde;es ARM e THUMB s&atilde;o implementados
como dois modos de opera&ccedil;&atilde;o diferentes, necessitando de uma instru&ccedil;&atilde;o especial para
trocar de modo.
Na gera&ccedil;&atilde;o 7 (Cortex) foi introduzido o conjunto de instru&ccedil;&otilde;es THUMB2 com
instu&ccedil;&otilde;es de 2 e 4 bytes que podem acessar todos os recursos do processador.
Desta forma podem-se usar instru&ccedil;&otilde;es de 16 bits ou de 32 bits arbitrariamente
sem que seja necess&aacute;rio trocar o modo de opera&ccedil;&atilde;o.
Nos processadores Cortex M0, M1, M2 e M3 existem apenas as instru&ccedil;&otilde;es THUMB2.
O suporte ao conjunto ARM &eacute; desabilitado.
Na fam&iacute;lia Cortex o processador de interrup&ccedil;&otilde;es NVIC foi incorporado
ao core do processador, de modo a tornar o uso de interrup&ccedil;&otilde;es mais simples
e mais eficiente que nos chips anteriores da fam&iacute;lia ARM.
===Mapa de Mem&oacute;ria===
Sistemas baseados no Cortex-M3 devem ter um mapa de mem&oacute;ria definido:
<table border=1>
<tr><td>0xFFFFFFFF<BR>
0xE0000000</td><td>Perif&eacute;ricos do sistema: NVIC, debug
</td></tr>
<tr><td>
0xDFFFFFFF<br>
0xA0000000
</td><td>Livre para Perif&eacute;ricos Externos
</td></tr>
<tr><td>
0x9FFFFFFF<br>
0x60000000</td>
<td>Livre para RAM Externa
</td></tr>
<tr><td>
0x5FFFFFFF<br>
0x40000000</td>
<td>Perif&eacute;ricos definidos pelo fabricante do CHIP
</td></tr>
<tr><td>
0x3FFFFFFF<br>
0x20000000</td>
<td>SRAM (Mem&oacute;ria integrada no CHIP)
</td></tr>
<tr><td>
0x1FFFFFFF<br>
0x00000000</td>
<td>Mem&oacute;ria FLASH integrada para firmware
</td></tr>
</table>
===O arquivo de registradores===
A arquitetura Cortex-M3, assim como o ARM7,  tem 16 registradores (R0 a R15) de 32bits com acesso direto &agrave; ULA.
Algumas instru&ccedil;&otilde;es THUMB s&oacute; podem acessar os registradores de R0 a R7.
Tres registradores tem prop&oacute;sito especial:
<dl>
<dt>R0 a R7 <dd> Registradores do usu&aacute;rio baixos: Todas as instru&ccedil;&otilde;es tem acesso.
<dt>R8 a R12 <dd> Registradores do usu&aacute;rio altos: Algumas instru&ccedil;&otilde;es THUMB n&atilde;o tem acesso.
<dt>R13 ou SP <dd>Stack Pointer. Apontador de pilha. Existem dois apontadores de pilha, ambos acess&iacute;veis como R3:
<ul><li><b>MSP</b> Main Stack Pointer: Este &eacute; o apontador de pilha principal, usado no n&uacute;cleo do sistema operacional
e no tratamento de exce&ccedil;&otilde;es.</li>
<li><b>PSP</b> Process Stack Pointer: Usada em programas aplicativos (modo usu&aacute;rio).
</ul>
As intru&ccedil;&otilde;es PUSH e POP armazenam ou restauram dados da pilha.
<pre class="code">
PUSH {R0} ; R13 = R13-4,  Memoria[R3] = R0
POP {R0} ; R0 = Memoria[R3], R13 = R13+4;
</pre>
As intru&ccedil;&otilde;es PUSH e POP podem usar uma lista de registradores:
<pre class="code">
PUSH {R0, R1, R2, R5}
POP {R0-R2, R5} ; Restaura R0, R1, R2 e R5
</pre>
</dd>
<dt>R14 ou LR <dd>Link Register. Cont&eacute; o endere&ccedil;o de retorno para chamadas de subrotina.
A instru&ccedil;&atilde;o BL <i>&lt;endere&ccedil;o &gt;</i> funciona como uma chamada de subrotina.
Ela salva automaticamete o endere&ccedil;o da
intru&ccedil;&atilde;o seuinte no LR e salta para o local indicado pelo operando.
Se for necess&aacute;rio aninhar chamadas de subrotina, o LR deve ser salvo na pilha.</dd>
<dt>R15 ou PC <dd>Program Counter. Este registrador tem o endere&ccedil;o da pr&oacute;xima instru&ccedil;&atilde;o
que ser&aacute; executada.</dd>
</dl>
====Registradores Especiais====
Fora do banco de registradores R0 a R15 existem alguns registradores que controlam ou indicam
aspectos especiais do processador.
Eles podem ser classificados em tres grupos:
<ul>
<li> '''xPSR''' -  APSR, IPSR, EPSR: ''Program Status Registers'': Tem os bits de estado da ULA: '''NZCVQ'''</li>
<li> PRIMASK, FAULTMASK e BASEPRI: Prioridade e mascaramento de interrup&ccedil;&otilde;es</li>
<li> CONTROL: Indica o modo de opera&ccedil;&atilde;o: Privilegiado, Usu&aacute;rio ou executando uma excess&atilde;o</li>
</ul>
Os bits NZCV do xPSR s&atilde;o chamados <i>"Condition Code"</i> abreviado como <i>cc</i>.
Em geral, os códigos cc refletem o resultado da &uacute;ltima instru&ccedil;&atilde;o da unidade aritm&eacute;tica.
<b>N</b> <i>Negative:</i> &Eacute; uma c&oacute;pia do bit mais significativo do resultado, que indica o
sinal. Resultado com bit mais significativo 1 &eacute; considerado como negativo. Setado, quando o resultado da operação for negativo, ou zerado, caso contrário
<b>Z</b> <i>Zero:</i> Indica que deu resultado ZERO na &uacute;ltima opera&ccedil;&atilde;o. Setado, quando o resultado da operação for zero, ou zerado, caso contrário
<b>C</b> <i>Carry:</i> Bit de transporte na soma ou empr&eacute;stimo na subtra&ccedil;&atilde;o. Setado, quando o resultado da operação resultar em um carry, ou zerado, caso contrário
<b>V</b> <i>oVerflow:</i> Indica overflow em uma opera&ccedil;&atilde;o com sinal. Ocorre quando mudou o sinal
sem a ativa&ccedil;&atilde;o do carry. Setado, quando o resultado da operação resultar em overflow, ou zerado, caso contrário
Um carry ocorre quando:
* o resultado de uma adição for maior ou igual a 2^32
* se o resultado de uma subtração for positivo ou zero
* como resultado de um deslocamento para a direita ou esquerda.
O overflow ocorre quando o resultado de uma soma, subtração, ou comparação for maior ou igual a 2^31, ou menor que -2^31.
Muitas instruções de processamento de dados podem atualizar as flags de condição do APSR, de acordo com o resultado da operação.
Algumas instruções vão atualizar todas as flags, e algumas, apenas um subconjunto.
Se a flag não for atualizada, o valor original é preservado.
Você pode executar uma instrução condicionalmente, baseado em um ou mais flags atualizadas por meio de outra instrução:
* imediatamente após a instrução que atualizou as flags;
* Após um determinado intervalo de instruções que não tenham atualizado as flags.
A execução condicional está disponível pelo uso condicional de branches, ou adicionando os sufixos ''cc'' às instruções.
[[image: MIPsufcc.png|center]]
Os sufixos de condição de código (cc) permitem ao processador testar uma condição baseado nas flags dos registradores. Se a condição falhar, a instrução:
* Não executa
* Não escreve nenhum valor no registrador de destino
* Não afeta nenhuma flag
* Não gera nenhuma exceção
Use as instruções CBZ e CBNZ para comparar o valor de um registrador com zero e desviar, dependendo do resultado.
Todas as instru&ccedil;&otilde;es tem um campo que permite a sua execu&ccedil;&atilde;o condicional de acordo
com o estado dos bits NZCV do xPSR. Na linguagem assembly esta execu&ccedil;&atilde;o condicional &eacute;
indicada por um sufixo de duas letras no mnemonico da instru&ccedil;&atilde;o de acordo com a tabela a seguir:
<table border=0 cellpadding=8><tr><td>
<table border=1>
<tr><th>cc</th><th>Condi&ccedil;&atilde;o</th>
<tr><td>CS</td><td>C=1 Carry Set</td></tr>
<tr><td>EQ</td><td>Z=1 Equal (zero)</td></tr>
<tr><td>VS</td><td>V=1 Overflow Set</td></tr>
<tr><td>GT</td><td>Greater Then [con sinal]</td></tr>
<tr><td>GE</td><td>Greater or Equal [com sinal]</td></tr>
<tr><td>PL</td><td>N=0 PLus (Positivo) [com sinal]</td></tr>
<tr><td>HI</td><td>HIgher (maior que) [sem sinal]</td></tr>
<tr><td>HS</td><td>Higher or Same [sem sinal]<br>O mesmo que CS</td></tr>
</table></td><td>
<table border=1>
<tr><th>cc</th><th>Condi&ccedil;&atilde;o</th>
<tr><td>CC</td><td>C=0 Carry Clear</td></tr>
<tr><td>NE</td><td>Z=0 Not Equal (n&atilde;o zero)</td></tr>
<tr><td>VC</td><td>V=0 Overflow Clear</td></tr>
<tr><td>LT</td><td>Less Then [com sinal]</td></tr>
<tr><td>LE</td><td>Less or Equal [com sinal]</td></tr>
<tr><td>MI</td><td>N=1 Minus</td></tr>
<tr><td>LO</td><td>Lower (menor que) [sem sunal]</td></tr>
<tr><td>LS</td><td>Lower or Same [sem sinal]</td></tr>
</table></td><td></tr>
</table>
<p>A maioria das instru&ccedil;&otilde;es pode afetar ou n&atilde;o os indicadores de estado no CPSR.
Na linguagem assembly coloca-se um sufixo com a letra <b>s</b> no mnemonico da instru&ccedil;&atilde;o
para indicar que os flags devem ser modificados.
Por exemplo:
<pre class="code">
subs R1, R2, R3 /* Calcula R1=R2-R3 e ajusta flags */
addge R4, R4, #1 /* Soma 1 no R4 se o resultado da subs for >= 0 */
AND R5, #7 /* R5 = R5 &amp; 7  Quado tem 2 operandos o destino=primeiro op */
</pre>
As instru&ccedil;&otilde;es de processamento de dados geralmente tem 3 argumentos:
<ul><li>op1: O primeiro argumento &eacute; um registrador onde o resultado &eacute; armazenado</li>
<li>op2: O segundo argumento &eacute; um registrador usado como primeiro operando da opera&ccedil;&atilde;o</li>
<li>op3: O terceiro argumento &eacute; o segundo operando da opera&ccedil;&atilde;o, que pode ser um valor imediato de 8 bits,
um registrador ou um registrador com deslocamento.</li>
</ul>
As instru&ccedil;&otilde;es de 3 argumentos s&atilde;o as seguintes:
<table border=1>
<tr><th colspan=3>instru&ccedil;&otilde;es de 3 argumentos</th></tr>
<tr><td>AND op1,op2,op3</td><td>op1 = op2 &amp; op3</td><td>E bit a bit</td></tr>
<tr><td>EOR op1,op2,op3</td><td>op1 = op2 ^ op3</td><td>Ou exclusivo</td></tr>
<tr><td>ADD op1,op2,op3</td><td>op1 = op2 + op3</td><td>Soma</td></tr>
<tr><td>SUB op1,op2,op3</td><td>op1 = op2 - op3</td><td>Subtra&ccedil;&atilde;o</td></tr>
<tr><td>RSB op1,op2,op3</td><td>op1 = op3 - op2</td><td>Subtra&ccedil;&atilde;o reversa</td></tr>
<tr><td>ADC op1,op2,op3</td><td>op1 = op2 + op3</td><td>Soma com carry</td></tr>
<tr><td>SBC op1,op2,op3</td><td>op1 = op2 - op3</td><td>Subtra&ccedil;&atilde;o com carry</td></tr>
<tr><td>RSC op1,op2,op3</td><td>op1 = op3 - op2</td><td>Subtra&ccedil;&atilde;o reversa com carry</td></tr>
<tr><td>ORR op1,op2,op3</td><td>op1 = op2 | op3</td><td>Ou bit a bit</td></tr>
<tr><td>BIC op1,op2,op3</td><td>op1 = op2 &amp; ~op3</td><td>Bit clear (zera bits)</td></tr>
</table>
Nas instru&ccedil;&otilde;es com 2 operandos o primeiro deve ser um registrador e o segundo
pode ser um valor imediato de 8 bits, um registrador ou um registrador com deslocamento.
====Exemplos de intru&ccedil;&otilde;es de 3 operandos:====
<pre class=code>
ORR R1, R2, #0x20 @ R1 = R2 | 0x20
ADD R2, R3, R4, LSL #3 @ R2 = R3 + (R4 &lt;&lt; 3)
RSB R4, R5, #0 @ R5 = 0 - R5
SUB R1, R2, R3, LSR R4 @ R1 = R2 - (R3 &gt;&gt; R4)
</pre>
<table border=1>
<tr><th colspan=3>instru&ccedil;&otilde;es de 2 argumentos</th></tr>
<tr><td>MOV op1, op2</td><td>op1 = op2</td><td>Copia op2 em op1</td></tr>
<tr><td>MVN op1, op2</td><td>op1 = ~op2</td><td>Copia op2 negado em op1</td></tr>
<tr><td>CMP op1, op2</td><td>op1 - op2</td><td>Compara: Subtrai ajustando CPSR sem armazenar o resultado</td></tr>
<tr><td>CMN op1, op2</td><td>op1 - ~op2</td><td>Compara com o segundo operando negado</td></tr>
<tr><td>TST op1, op2</td><td>op1 &amp; op2</td><td>Testa bits: Faz E ajustando CPSR sem armazenar o resultado</td></tr>
<tr><td>TEQ op1, op2</td><td>op1 ^ op2</td><td>Testa bits: Faz XOR ajustando CPSR sem armazenar o resultado</td></tr>
</table>
====Instru&ccedil;&otilde;es de leitura da mem&oacute;ria====
Nesta listagem Rd e Re podem ser registradores R0 a R15.
Rd &eacute; o registrador que recebe o valor lido da mem&oacute;ria; Re &eacute; o reg que cont&eacute;m o endere&ccedil;o de
mem&oacute;ria que ser&aacute; lido. <tt>offset</tt> &eacute; uma constante positiva ou negaiva de 12 bits usada
para modificar o endere&ccedil;o.
<table border=1>
<tr><th colspan=3>Instru&ccedil;&otilde;es de leitura da Mem&oacute;ria para Registrador</th></tr>
<tr><td>LDR Rd,[Re, #offset]</td><td> Rd := mem&oacute;ria[Re + offset]; </td><td>Le 32 bits</td></tr>
<tr><td>LDRH Rd,[Re, #offset]</td><td> Rd := mem&oacute;ria[Re + offset]; </td><td>Le 16 bits (Half word)</td></tr>
<tr><td>LDRB Rd,[Re, #offset]</td><td> Rd := mem&oacute;ria[Re + offset]; </td><td>Le 8 bits (Byte)</td></tr>
<tr><td>LDR Rd,[Re, #offset]!</td><td> Rd := mem&oacute;ria[Re + offset];<br>Re := Re + offset; </td><td>Le 32 bits
e modifica Re</td></tr>
<tr><td>LDR Rd,[Re, Ri]</td><td>Rd := mem&oacute;ria[Re + Ri]</td><td>Le mem&oacute;ria com endere&ccedil;o formdo
pela soma de 2 registradores</td></tr>
<tr><td>LDR Rd,[Re], #offset</td><td> Rd := mem&oacute;ria[Re];<br>Re := Re + offset; </td><td>Le 32 bits
e modifica Re com p&oacute;s incremento</td></tr>
</table>
====Instru&ccedil;&otilde;es de escrita na mem&oacute;ria====
Nesta listagem Rf e Re podem ser registradores R0 a R15.
Rf &eacute; o registrador que ser&aacute; armazenado na mem&oacute;ria; Re &eacute; o reg que cont&eacute;m o endere&ccedil;o na
mem&oacute;ria. <tt>offset</tt> &eacute; uma constante positiva ou negaiva de 12 bits usada
para modificar o endere&ccedil;o.
<table border=1>
<tr><th colspan=3>Instru&ccedil;&otilde;es escrita de Registrador na Mem&oacute;ria</th></tr>
<tr><td>STR Rf,[Re, #offset]</td><td> mem&oacute;ria[Re + offset]:= Rf; </td><td>Escreve 32 bits</td></tr>
<tr><td>STRH Rf,[Re, #offset]</td><td> mem&oacute;ria[Re + offset]:= Rf; </td><td>Escreve 16 bits (Half word)</td></tr>
<tr><td>STRB Rf,[Re, #offset]</td><td> mem&oacute;ria[Re + offset]:= Rf; </td><td>Escreve 8 bits (Byte)</td></tr>
<tr><td>STR Rf,[Re, #offset]!</td><td> mem&oacute;ria[Re + offset]:= Rf;<br>Re := Re + offset; </td><td>Le 32 bits
e modifica Re</td></tr>
<tr><td>STR Rd,[Re], #offset</td><td> mem&oacute;ria[Re]:= Rf;<br>Re := Re + offset; </td><td>Escreve 32 bits
e modifica Re com p&oacute;s incremento</td></tr>
</table>
====Instru&ccedil;&otilde;es de salto====
Salto relativo ao PC:
<pre class=code>
B enderco_destino @ Salto incondicional
BEQ iguais @ Salta se Z=1 (Iguais)
BCS carry_set
</pre>
====Chamada de subrotina:====
<pre class=code>
BL subrotina1
</pre>
A instru&ccedil;&atilde;o <tt>BL</tt> salva o endere&ccedil;o de retorno no R14 (que &eacute; o LR Link-Rgister) e
salta para a subrotina. Para reornar, da subrotina pode-se copiar o LR no PC com
<pre class=code>
subrotina1:
@ Opera&ccedil;&otilde;es da subrotina
MOV PC,LR @ Retorna da subrotina
</pre>
O m&eacute;todo acima n&atilde;o &eacute; aninh&aacute;vel. N&atilde;o se poderia chamar outra subrotina de dentro desta subrotina
porque o valor do LR seria alterado.
<br>Subrotinas que chamam subrotinas, devem salvar o LR na pilha:
<pre class=code>
subrotina2:
PUSH {R1, R2, LR} @ Salva na pilha R1, R2, LR
@ Opera&ccedil;&otilde;es da subrotina
POP {R1, R2, PC} @ Restaura R1 e R2 e retorna da subrotina
</pre>
-----------
==Referências==
Maiores informações sobre programação em ARM:
  [[media: MIPM3TUG.pdf|'''The Definitive Guide to the ARM CORTEX-M3''', 2nd ed]]
-------------
-------------
{| border="1" cellpadding="5" cellspacing="0"  
{| border="1" cellpadding="5" cellspacing="0"  
! style="background: #00ff00;" | [[MIP| << Página da disciplina ]]  
! style="background: #00ff00;" | [[MIP| << Página da disciplina ]]  
! style="background: #cdc5bf;" | [[AULA 4 - Microprocessadores - Graduação | < Aritmética Binária ]]  
! style="background: #cdc5bf;" | [[AULA 4 - Microprocessadores - Graduação | Aritmética computacional < ]]  
! style="background: #cdc5bf;" | Aula 5 - Conjunto de instruções
! style="background: #cdc5bf;" | Aula 5 - Conjunto de instruções genéricas de microprocessador
! style="background: #cdc5bf;" | [[AULA 7 - Microprocessadores - Graduação | Estrutura e Funcionamento da CPU > ]]
! style="background: #cdc5bf;" | [[AULA 5-2 - Microprocessadores - Graduação | Conjunto de instruções do ARM > ]]
|}
|}

Edição atual tal como às 12h26min de 7 de outubro de 2025

CONJUNTOS DE INSTRUÇÕES GENÉRICAS DE MICROPROCESSADORES

Um programador de linguagem de alto nível normalmente conhece muito pouco acerca da arquitetura da máquina que está usando.

O conjunto de instruções da máquina é o limite em que o projetista de CPU e o programador de baixo nível enxergam, da mesma máquina.

Implementar uma CPU é uma tarefa que envolve, em grande parte, implementar um conjunto de instruções de máquina.

Já programar em linguagem de máquina (na verdade, em linguagem de montagem, Assembly) exige um conhecimento acerca do conjunto de registradores da CPU, a estrutura de memória, os tipos de dados disponíveis na máquina e o funcionamento da ULA.

Porém, da descrição do conjunto de instruções à uma compreensão sobre o funcionamento da CPU, há um longo caminho.

CARACTERÍSTICAS DE INSTRUÇÕES DE MÁQUINA

A operação de uma CPU é determinada pelas instruções que ela executa, conhecidas como instruções de máquina.

A coleção de instruções que uma determinada CPU é capaz de executar é conhecida como conjunto de instruções da CPU.

Elementos de instrução de máquina

Cada instrução deve conter toda a informação necessária para que a CPU possa executá-la.

MIPcicloinst.png

A figura acima ajuda a definir os elementos da instrução:

  • Código de operação (OPCODE) - Especifica a operação a ser efetuada (por exemplo, ADD, ou E/S, etc). A operação é especificada por um código binário.

Ex: Palavra de seleção (SMCn) em uma ULA de 4 bits

  • Referência a operando fonte - a operação pode envolver um ou mais operandos fonte, ou seja, que constituem dados de entrada para a operação. Exemplos:
    • operação com um único operando: INV(A)
    • operação com dois operandos: ADD(A,B)
    • operação com três ou mais operandos: DEV(GE(A,B),C,D)
  • Referência a um operando de destino - a operação pode eventualmente produzir um resultado, que deverá ser enviado a um endereço de memória, ou registrador
  • Endereço da próxima instrução - indica aonde a CPU deve buscar a próxima instrução (memória principal ou virtual), depois que a instrução corrente for completada, quando for o caso.

Os operandos fonte e destino podem estar localizados em:

  • Memória principal ou virtual - implica em busca na memória RAM, ou no HD (quando virtual)
  • Registrador da CPU - se houver apenas um registrador, a referência a ele poderá ser implícita. Quando há acumulador, a referência a ele é default. Caso hajam vários registradores, normalmente a referência a cada um, individualmente, é feita por um número inteiro correspondente.
  • Dispositivo de E/S - indicado diretamente na instrução. Se for usada a E/S mapeada na memória, esta informação se resumirá a um endereço de memória, como os demais. Pode ser também um registrador específico (Ex: porta serial).

REPRESENTAÇÃO DE INSTRUÇÕES

Internamente, cada instrução é representada por uma sequência de bits.

É dividida em campos, correspondentes aos elementos da instrução.

Exemplos:

MIPformatinst.png


MIPformatinstias.png
MIPinstarm.png

A maioria das CPUs têm mais de um formato de instrução.

Durante a execução, uma instrução é lida em um registrador de instruções (IR) da CPU. A CPU extrai os dados dos vários campos da instrução e efetua a operação correspondente.

Os códigos de operação normalmente são representados por abreviações, chamadas mnemônicos, que evitam que os programadores tenham que trabalhar diretamente com valores binários.

Alguns exemplos mais comuns são:

ADD  -------------  Adição
SUB  -------------  Subtração
MPY  -------------  Multiplição
DIV  -------------  Divisão
GT   -------------  Operação >
LT   -------------  Operação <
GE   -------------  Operação ≥
LE   -------------  Operação ≤

Os operandos também são representados por símbolos.

Por exemplo:

  ADD R, Y

pode significar adicionar o valor contido na posição Y, com o valor contido no registrador R. Neste caso, Y é um endereço de memória e R, um registrador da própria CPU.


Exercício

Em uma ULA de inteiros de 4 bits, com formato de instrução [OPCODE(5) A(4) B(4)], qual seria a instrução correspondente, se a intenção fosse executar a operação lógica Y = OR(A', B) , com A = 0001b e B = 1010?

NÚMERO DE ENDEREÇOS

Uma das maneiras tradicionais de se descrever uma arquitetura é em termos do número de endereços contidos em cada instrução.

Obviamente, instruções aritméticas e lógicas requerem um número maior de operandos (e de endereços, por conseguinte). Normalmente, precisam de dois operandos que serão submetidos a um cálculo ou comparação, e de um terceiro, pra armazenar o resultado.

O endereço da próxima instrução normalmente é implícito, armazenado no registrador PC.

A figura abaixo compara o que seriam instruções típicas de um, dois ou três endereços, para computar a mesma linha de programação:

Y = (A - B) / (C + D x E)
MIPinstrxend.png

Note que as instruções com 3 endereços implementaram o comando com apenas 4 instruções de máquina. Porém, instruções de 3 endereços não são muito comuns, porque implicam em instruções grandes.

No caso das instruções de 2 endereços, foram necessárias 6 linhas de código, duas a mais, portanto. Nestas instruções é típico que um dos endereços referencie tanto o operando, quanto o resultado. Gera opcodes menores, porém gera códigos maiores e exige maior habilidade do programador.

As instruções de 1 único endereço exigem que um segundo endereço seja sempre implícito (normalmente, o Acumulador - AC). Neste caso, foram necessárias 8 instruções para resolver o problema.

É possível também usar-se em expressões aritméticas uma instrução com ZERO endereço. Neste caso, é necessária uma organização de memória especial, chamada pilha. As instruções com zero endereço sempre referenciam os valores nas duas posições no topo da pilha.

NÚMERO DE ENDEREÇOS Representação simbólica Interpretação
3 OP A, B, C A ← B OP C
2 OP A, B A ← A OP B
1 OP A AC ← AC OP A
0 OP T ← (T-1) OP T


Além de tudo que foi citado, as instruções podem variar muito de tamanho porque o endereço em questão de cada operando pode se referir à memória física ou a um dos registradores da CPU. Como as memórias são muito maiores que o número de registradores, vão utilizar endereços muito mais longos.

Assim, existem máquinas que, quando vão endereçar um valor NA MEMÓRIA externa (RAM) utilizam mais de uma instrução para acessar o dado.

Tudo sempre vai depender da arquitetura da máquina.


TIPO DE INSTRUÇÃO

Como já vimos, uma única instrução escrita em linguagem de alto nível pode requerer várias instruções de máquina.

Os tipos de instrução de máquina que existem são:

  • Processamento de dados - instruções aritméticas e lógicas
  • Armazenamento/transferência de dados - instruções de memória
  • Movimentação de dados - instruções de E/S
  • Controle - instruções de teste e de desvio
MIPtiposinst.png
MIPtiposinst2.png

Na maioria das vezes, as instruções são auto-explicativas.

As instruções do tipo transferência de controle, no entanto, podem ser muito complexas. Em todos os casos, exceto com elas a próxima instrução a ser executada é aquele que segue imediatamente a atual, na memória.

Nas instruções de transferência de controle, a CPU atualiza o PC com o endereço de alguma outra instrução, armazenada na memória de programa.

As instruções de transferência de controle são aquelas utilizadas quando há loops no código, ou comandos de decisão ou ainda quando o código teve que ser segmentado em vários arquivos, normalmente porque estava muito extenso.

Instruções de desvio

Nestas, um dos operandos é o endereço da próxima instrução a ser executada.

Com frequência, essa instrução é do tipo desvio condicional, isto é, o desvio só ocorrerá se uma determinada condição for satisfeita. Caso contrário, o programa segue com a próxima instrução adjacente, sem alterações no PC além do incremento normal.

Estas instruções normalmente têm o nome de BRANCH ou JUMP e podem depender de uma condição, ou ser incondicionais.

Exemplo:

MIPbranch.png

Instruções de Chamada de procedimento

Um procedimento, ou função, ou ainda subrotina é um trecho de código independente que modulariza um programa.

O mecanismo de controle de procedimentos envolve duas instruções básicas: uma instrução de chamada, que desvia a instrução corrente para o início do procedimento, e uma instrução de retorno, que provoca o retorno da execução para o endereço onde ocorreu a chamada. Ambas são condições de desvio.

A figura abaixo ilustra o uso de procedimentos na execução de um programa.

MIPproceds.png

INSTRUÇÕES DO PENTIUM II E DO POWERPC

Para exemplificar, apresentamos o caso especial de conjunto de instruções de um processador de propósito geral que foi muito utilizado até o início da década de (20)00.

MIPconjp21.png
MIPconjp22.png
MIPconjp23.png



<< Página da disciplina Aritmética computacional < Aula 5 - Conjunto de instruções genéricas de microprocessador Conjunto de instruções do ARM >