imported>Fargoud |
imported>Fargoud |
| (6 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 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 sintaxe é:
| |
|
| |
| ===Instruções de acesso à memória===
| |
|
| |
| '' <LDR|STR> {cond} {B} {T} Rd,<Address>''
| |
|
| |
| onde:
| |
| * ''LDR'' carrega um valor da memória para um registrador
| |
| * ''STR'' armazena um valor de registrador para a memória
| |
| * ''{cond}'' mnemônico condicional de 2 caracteres
| |
| *''{B}'' se B estiver presente, transfere um byte, senão, transfere uma palavra
| |
| *''{T}'' se T estiver presente, the bit ''W'' será setado em um instrução pós-indexada, forçando um modo não-privilegiado para o ciclo de transferência. Não permitido para modo pré-indexado.
| |
| *''Rd'' é o nome do registrador
| |
| *''<Address>'' pode ser:
| |
| **Uma expressão que gere um endereço:
| |
| <expression>
| |
| **Uma especificação de endereço pré-fixada:
| |
| ''[Rn]'' endereço base
| |
| ''[Rn,<#expression>]{!}'' offset de ''<expression>'' bytes
| |
| ''[Rn,{+/-}Rm{,<shift>}]{!}'' offset de +/- conteúdos do registrador de índice, deslocado de ''<shift>''
| |
| **Uma especificação de endereçamento pós-fixada:
| |
| ''[Rn],<#expression>'' offset de ''<expression>'' bytes
| |
| ''[Rn],{+/-}Rm{,<shift>}'' offset de +/- conteúdos do registrador de índice, deslocado de ''<shift>''
| |
|
| |
| ===Exemplo1===
| |
|
| |
| STR R1,[R2,R4] ; Armazena R1 em R2+R4 (ambos os quais são
| |
| ; registradores)
| |
| STR R1,[R2],R4 ; Armazena R1 em R2 e atualiza o endereço
| |
| ; em R2 com R2+R4.
| |
| LDR R1,[R2,#16] ; Carrega R1 do endereço R2+16, mas
| |
| ; não atualiza R2.
| |
| LDR R1,[R2,R3,LSL#2] ; Carrega R1 do endereço R2+R3*4 - SÓ FUNCIONA NO VISUAL ARM
| |
| LDREQBR1,[R6,#5] ; Carrega condicionalmente o byte de R6+5 em
| |
| ; R1 bits 0 a 7, preenchendo os bits 8 a 31
| |
| ; com zeros.
| |
| STR R1,PLACE ; Gera um offset em PC relativo ao
| |
| ; endereço PLACE.
| |
|
| |
| ===Exemplo2===
| |
|
| |
| Salva valores em endereços de memória pré-fixados e pós-fixados.
| |
| Para rodar no VisualArm (por causa da sintaxe e acesso à memória):
| |
|
| |
| mov r1,#0x1000
| |
| mov r2,#0x4
| |
| mov r3,#0x10
| |
| mov r4,#0x20
| |
| mov r5,#250
| |
| mov r6,#140
| |
| mov r7,#240
| |
| mov r8,#1
| |
| mov r9,#2
| |
| mov r10,#3
| |
| mov r11,#4
| |
| str r5,[r1,r2] ; salva 250d (FAh) no endereço 1004h
| |
| str r6,[r1,r3] ; salva 140d (8Ch) no endereço 1010h
| |
| str r7,[r1,r4] ; salva 240d (F0h) no endereço 1020h
| |
| str r8,[r1],r2 ; salva 1d no endereço 1000h e faz R1=1004h
| |
| str r9,[r1],r2 ; salva 2d no endereço 1004h e faz R1=1008h
| |
| str r10,[r1],r2 ; salva 3d no endereço 1008h e faz R1=100Ch
| |
| str r11,[r1],r2 ; salva 4d no endereço 100Ch e faz R1=1010h
| |
|
| |
| ===Exemplo3===
| |
|
| |
| Para rodar no VisualArm (por causa da sintaxe e acesso à memória):
| |
|
| |
| mov r1,#0x1000 ;endereço base
| |
| mov r2,#0x4 ;incremento de endereços
| |
| mov r3,#1 ;contadora de dados
| |
| mov r4,#20 ;contadora de endereços
| |
| loop str r3,[r1],r2 ; salva dado no endereço em R1 e faz R1=R1+4
| |
| add r3,r3,#1 ; incrementa dado
| |
| sub r4,r4,#1 ; decrementa contadora endereços
| |
| cmp r4,#0 ; compara contadora com endereço final
| |
| ble fim ; termina se já zerou R4
| |
| b loop ; continua se ainda não atingiu 20 endereços
| |
| fim
| |
|
| |
| ===Exemplo 4===
| |
|
| |
| Para rodar no VisualArm (por causa da sintaxe e acesso à memória):
| |
|
| |
| mov r1,#0x1000 ;endereço base
| |
| mov r2,#0x4 ;incremento de endereços
| |
| mov r3,#1 ;contadora de dados
| |
| mov r4,#20 ;contadora de endereços
| |
| loop mov r5,r1 ; registrador ponteiro
| |
| str r3,[r1],r2 ; salva dado no endereço em R1 e faz R1=R1+4
| |
| add r3,r3,#1 ; incrementa dado
| |
| sub r4,r4,#1 ; decrementa contadora endereços
| |
| ldr R6,[R5] ; Carrega dado do último endereço atualizado
| |
| cmp r4,#0
| |
| ble fim
| |
| b loop
| |
| fim
| |
|
| |
|
| |
| A arquitetura ARM suporta dois tipos de instruções de load e store que transferem o conteúdo de um registrador para a memória ou ao contrário.
| |
|
| |
| O primeiro tipo pode carregar ou escrever uma palavra 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 '''para rodar no VISUAL:'''
| |
| ;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
| |
|
| |
| Programa calculadora simples 4 op '''para rodar no ARMSIM:'''
| |
| ;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:=
| |
|
| |
|
| |
| Lê um inteiro do arquivo ''ArqEntrada.txt'':
| |
|
| |
| InFileName: .asciz "ArqEntrada1.txt"
| |
| InFileError: .asciz "Não foi possível abrir\n"
| |
| .align
| |
| InFileHandle:.word 0
| |
| ldr r0,=InFileName ; configura o nome do arquivo a ser aberto
| |
| mov r1,#0 ; modo leitura
| |
| swi 0x66 ; abre arquivo para leitura
| |
| bcs InFileError ; se houver erro
| |
| ldr r1,=InFileHandle ;carrega handle de arquivo para leitura
| |
| str r0,[r1] ; salva o handle
| |
| ldr r0,=InFileHandle
| |
| ldr r0,[r0]
| |
| swi 0x6c ;lê inteiro do arquivo aberto
| |
| bcs ReadError
| |
| ReadError: swi 0x68
| |
|
| |
| =Exemplo 3:=
| |
|
| |
|
| |
| 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,#80
| |
| 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 ; R5 = 0 - R4
| |
| SUB R1, R3, R2, LSR R4 ;R1 = R3 - (R2 >> R4)
| |
|
| |
| =Exemplo 4:=
| |
|
| |
| Programa que executa multiplicação sem uso da instrução MUL e checando se os operandos são negativos:
| |
|
| |
| ; EXERCÍCIO 2 DISCIPLINA MICROPROCESSADORES
| |
| ; PROFA. FERNANDA
| |
| ; AULA 26/03/2019
| |
| mov r0,#8
| |
| mov r1,#-5
| |
| mov r4,#0 ; registrador de SAÍDA
| |
| inicio
| |
| cmp r1,#0
| |
| beq fim ;r1 = 0 -> r4 = 0
| |
| bgt set ;r1 >0
| |
| ; r1 negativo:
| |
| rsb r3, r1, #0
| |
| rsb r2,r0, #0
| |
| b loop
| |
| set
| |
| mov r3,r1
| |
| mov r2,r0
| |
| loop
| |
| add r4,r4,r2
| |
| sub r3, r3, #1
| |
| cmp r3,#0
| |
| ble fim
| |
| b loop
| |
| fim
| |
|
| |
| =Exemplo 5:=
| |
|
| |
| Programa que armazena um valor NA MEMÓRIA:
| |
|
| |
| mov R0, #255
| |
| mov R3, #2000
| |
| mov R1, #0
| |
| str R0, [R3, R1]
| |
|
| |
| =Exemplo 6:=
| |
|
| |
| Programa que armazena valores em espaços seguidos da memória:
| |
|
| |
| mov R0, #255
| |
| mov R1, #0
| |
| mov R2, #100 //100 endereços depois do endereço-base
| |
| mov R3, #2000 //endereço base
| |
| loop
| |
| str R0, [R3,R1]
| |
| add R1, R1, #4 //endereços têm que ser múltiplos de 4
| |
| add R0, R0, #1
| |
| cmp R1, R2
| |
| blt loop
| |
| ldr R5,[R3,#20]
| |
|
| |
| Ao final da execução, R3 continua contendo o valor 0X7D0 (endereço base = 2.000d)
| |
|
| |
| =Exemplo 7:=
| |
|
| |
| Programa que armazena valores em espaços seguidos da memória e atualiza variável:
| |
|
| |
| mov R0, #255
| |
| mov R1, #0
| |
| mov R2, #100 //100 endereços depois do endereço-base
| |
| mov R3, #2000 //endereço base
| |
| loop
| |
| str R0, [R3,R1]!
| |
| add R1, R1, #4 //endereços têm que ser múltiplos de 4
| |
| add R0, R0, #1
| |
| cmp R1, R2
| |
| blt loop
| |
| ldr R5,[R3,#-200]
| |
|
| |
| Ao final da execução, R3 contém o valor 0X908 (endereço base = 2.312d)
| |
|
| |
| =Exemplo 8:=
| |
|
| |
| Programa que salva dois vetores de 8 valores na memória (A, no endereço 2000 e B, no endereço 2032) e executa a operação:
| |
|
| |
| c = ∑ Ai.Bi, com i variando de 0 a 7.
| |
|
| |
| O produto final C será armazenado no endereço 1000 da memória
| |
|
| |
| mov R0, #4 ; passo de memória
| |
| mov R10, #02000 ;endereço de A
| |
| mov R11, #02032 ;endereço de B
| |
| mov R12, #0x1000 ;endereço de C
| |
|
| |
| ;valores do vetor A
| |
| mov R2, #30
| |
| mov R3, #27
| |
| mov R4, #21
| |
| mov R5, #17
| |
| mov R6, #10
| |
| mov R7, #3
| |
| mov R8, #-1
| |
| mov R9, #-2
| |
|
| |
| ;grava valores de A na memória
| |
| mov R1, R10
| |
| str R2, [R1],R0
| |
| str R3, [R1],R0
| |
| str R4, [R1],R0
| |
| str R5, [R1],R0
| |
| str R6, [R1],R0
| |
| str R7, [R1],R0
| |
| str R8, [R1],R0
| |
| str R9, [R1]
| |
|
| |
| ;valores do vetor B
| |
| mov R2, #-3
| |
| mov R3, #1
| |
| mov R4, #7
| |
| mov R5, #11
| |
| mov R6, #13
| |
| mov R7, #23
| |
| mov R8, #4
| |
| mov R9, #5
| |
|
| |
| ;grava valores de B na memória
| |
| mov R1, R11
| |
| str R2, [R1],R0
| |
| str R3, [R1],R0
| |
| str R4, [R1],R0
| |
| str R5, [R1],R0
| |
| str R6, [R1],R0
| |
| str R7, [R1],R0
| |
| str R8, [R1],R0
| |
| str R9, [R1]
| |
|
| |
| ;rotina para multiplicação dos valores
| |
| mov R1, R10
| |
| mov R2, R11
| |
| mov R3, #0
| |
| mov R4, #7
| |
| mov R8, #0 ;registrador de saída
| |
|
| |
| somatorio mov R5, #0
| |
| ldr R6, [R1],R0
| |
| ldr R7, [R2],R0
| |
| cmp R7, #0
| |
| bge multpos ;se 2o op >0 => mult positiva
| |
| beq final ;se 2o op = 0 => não acumula
| |
|
| |
| ;se 2o. op < 0 :
| |
| multneg sub R5, R5, R6
| |
| add R7, R7, #1
| |
| cmp R7, #0
| |
| bne multneg
| |
| b final
| |
|
| |
| multpos add R5, R5, R6
| |
| sub R7, R7, #1
| |
| cmp R7, #0
| |
| bne multpos
| |
|
| |
| final add R8, R8, R5
| |
| add R3, R3, #1
| |
| cmp R3, R4
| |
| ble somatorio
| |
|
| |
| str R8, [R12]
| |
|
| |
| =Exemplo 9:=
| |
|
| |
| NomeArqEntrada: .asciz "ArqEntrada1.txt"
| |
| ErroArqEntrada: .asciz "Não foi possível abrir\n"
| |
| ArqEntrHandle:.word 0
| |
| .align
| |
| NomeArqSaida: .asciz "ArqSaida.txt"
| |
| ArqSaidaHandle: .word 0
| |
| Saidasoma: .asciz "Soma = "
| |
| Saidasub: .asciz "Subtracao = "
| |
| Saidamult: .asciz "Multiplicacao = "
| |
| Saidadiv1: .asciz "Divisao = "
| |
| Saidadiv2: .asciz "; Resto = "
| |
| Saidafim: .asciz "Fim\n"
| |
| ;**** ABRE ARQUIVO DE ENTRADA PARA LEITURA
| |
| mov r1,#0 ; abre arquivo, modo leitura (0)
| |
| ldr r0,=NomeArqEntrada ; configura o nome do arquivo a ser aberto
| |
| swi 0x66 ; abre arquivo para leitura
| |
| bcs HouveErro ; se houver erro
| |
| ldr r1,=ArqEntrHandle
| |
| str r0,[r1]
| |
| swi 0x6c ;lê inteiro do arquivo aberto. Handle tem que estar em R0. Após-> R0 = inteiro
| |
| mov r4,r0 ; move inteiro lido para R4 - operação da calculadora selecionada!!!
| |
| ;FECHA ARQUIVO DE ENTRADA
| |
| ldr r1,=ArqEntrHandle
| |
| ldr r0,[r1]
| |
| swi 0x68 ; fechar arquivo
| |
|
| |
| ;***** ABRIR ARQUIVO DE SAÍDA PARA IMPRIMIR RESULTADOS
| |
| mov r1, #1 ; abrir arq modo ESCRITA - append (adiciona sem apagar o que já tinha)
| |
| ldr r0, =NomeArqSaida; ; configura o nome do arquivo a ser aberto
| |
| swi 0x66 ;abre arq para escrita
| |
| bcs HouveErro ; se houver erro
| |
| ldr r1,=ArqEntrHandle
| |
| str r0,[r1]
| |
| ldr r1,=Saidasoma ;r1 = endereço da string de saída
| |
| swi 0x69 ;escreve string no arquivo
| |
|
| |
| ;******
| |
| mov r5,#6
| |
| mov r6,#2
| |
| mov r7,#0
| |
| cmp r4,#1
| |
| blt result
| |
| beq soma
| |
| ;******
| |
| cmp r4,#2
| |
| beq subt
| |
| ;******
| |
| cmp r4,#3
| |
| beq mult
| |
| ;******
| |
| cmp r4,#4
| |
| bgt result
| |
| beq divisao
| |
| ;******
| |
| soma: add r7,r5,r6
| |
| ldr r0,=Saidasoma ; address of a null terminated ASCII string
| |
| swi 0x02 ; Display String on Stdout
| |
| add r0,r7,#'0
| |
| swi 0x00 ;Display Character on Stdout
| |
| ;*** Escreve resultados agora no arquivo de saída
| |
| ldr r9,=ArqSaidaHandle
| |
| ldr r0, [r9]
| |
| ldr r1,=Saidasoma ;R1 = address of string
| |
| swi 0x69 ;output string to file
| |
| mov r1, r7
| |
| swi 0x6b ;escreve o resultado no arquivo
| |
| b result
| |
|
| |
| subt: sub r7,r5,r6
| |
| ldr r0,=Saidasub ; address of a null terminated ASCII string
| |
| swi 0x02 ; Display String on Stdout
| |
| add r0,r7,#'0
| |
| swi 0x00 ;Display Character on Stdout
| |
| ldr r9,=ArqSaidaHandle
| |
| ldr r0, [r9]
| |
| ldr r1,=Saidasub ;R1 = address of string
| |
| swi 0x69 ;output string to file
| |
| mov r1, r7
| |
| swi 0x6b ;escreve o resultado no arquivo
| |
| b result
| |
|
| |
| mult: mul r7,r5,r6
| |
| ldr r0,=Saidamult ; address of a null terminated ASCII string
| |
| swi 0x02 ; Display String on Stdout
| |
| add r0,r7,#'0
| |
| swi 0x00 ;Display Character on Stdout
| |
| ldr r9,=ArqSaidaHandle
| |
| ldr r0, [r9]
| |
| ldr r1,=Saidamult ;R1 = address of string
| |
| swi 0x69 ;output string to file
| |
| mov r1, r7
| |
| swi 0x6b ;escreve o resultado no arquivo
| |
| b result
| |
|
| |
| divisao: mov r8,r5
| |
| div2: subge r8,r8, r6
| |
| add r7, r7,#1
| |
| cmp r8,r5
| |
| bge div2
| |
| ldr r0,=Saidadiv1 ; address of a null terminated ASCII string
| |
| swi 0x02 ; Display String on Stdout
| |
| add r0,r7,#'0
| |
| swi 0x00
| |
| mov r0,#'\0
| |
| swi 0x00 ;Display Character on Stdout
| |
| ldr r0,=Saidadiv2 ; address of a null terminated ASCII string
| |
| swi 0x02 ; Display String on Stdout
| |
| add r0,r8,#'0
| |
| swi 0x00 ;Display Character on Stdout
| |
| ldr r9,=ArqSaidaHandle
| |
| ldr r0, [r9]
| |
| ldr r1,=Saidadiv1 ;R1 = address of string
| |
| swi 0x69 ;output string to file
| |
| mov r1, r7
| |
| swi 0x6b ;escreve o resultado no arquivo
| |
| b result
| |
| fim:
| |
|
| |
| bcs HouveErro ; se houver erro
| |
|
| |
| result:
| |
| ;***** MONTA STRING RESULTADOS
| |
| ldr r1,=ArqSaidaHandle ; load the file handle
| |
| ldr r0,[r1]
| |
| swi 0x68 ; fechar arquivo
| |
|
| |
| HouveErro: swi 0x68 ; fechar arquivo
| |
|
| |
| =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]]
| |
| # Escreva o programa com menu para resolver operações '''lógicas''' E, OU e NÃO entre dois valores armazenados em R4 e R5, assumindo que a variável é ''false'' quando tiver valor igual a 0 (=0).
| |
| # Implemente o programa que calcula (X * 2^N), apenas pelos deslocamentos à esquerda ou direita, de um valor X armazenado em R0 e com N armazenado em R1.
| |
| # Expanda o programa da calculadora de 4 operações para que ela também calcule potenciação, isto é, R3 = R2^R1. [[Exemplo de solução para potenciaçã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.
| |
|
| |
| [[image: LSRS.png|center]]
| |
|
| |
| ===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
| |
|
| |
| mov r1, #-200
| |
| mov r2, #200
| |
| mov r3, #5
| |
|
| |
| asr r9, r1, #3
| |
| lsls r5, r2, #4
| |
| lsl r4, r3, #6
| |
| ror r6, r1, #6
| |
| rrx r7, r3
| |
|
| |
| ==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 Rd, Rf, Rn - realiza uma operação E bit-a-bit entre Rf e ~(Rn) e coloca o resultado em Rd.
| |
| 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:
| |
|
| |
| mov r1, #16
| |
| mov r2, #36
| |
| loop cmp r1, r2 ; cmp sempre atualiza flags
| |
| ble neg ; queremos testar se r1 > r2
| |
| subgt r1, r1, r2 ; se r1 > r2, faça r1:=r1-r2
| |
| bne loop
| |
| neg ; senão teste por <
| |
| sublt r2, r2, r1 ; se r1 < r2 faça r2:= r2 -r1
| |
| bne loop
| |
|
| |
|
| |
| -------------------
| |
| 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ções da arquitetura
| |
| ARM tem tamanho regular de 32 bits (4 bytes)
| |
|
| |
| Na geração 4 de processadores ARM (Tipo ARM7-TDMI) foi incuido o conjunto
| |
| de instruções alternativo THUMB em que a maioria das instruções tem 2 bytes.
| |
|
| |
| Nos processadores ARM7-TDMI os conjuntos de instruções ARM e THUMB são implementados
| |
| como dois modos de operação diferentes, necessitando de uma instrução especial para
| |
| trocar de modo.
| |
|
| |
| Na geração 7 (Cortex) foi introduzido o conjunto de instruções THUMB2 com
| |
| instuções de 2 e 4 bytes que podem acessar todos os recursos do processador.
| |
|
| |
| Desta forma podem-se usar instruções de 16 bits ou de 32 bits arbitrariamente
| |
| sem que seja necessário trocar o modo de operação.
| |
|
| |
| Nos processadores Cortex M0, M1, M2 e M3 existem apenas as instruções THUMB2.
| |
| O suporte ao conjunto ARM é desabilitado.
| |
|
| |
| Na família Cortex o processador de interrupções NVIC foi incorporado
| |
| ao core do processador, de modo a tornar o uso de interrupções mais simples
| |
| e mais eficiente que nos chips anteriores da família ARM.
| |
|
| |
|
| |
| ==Mapa de Memória==
| |
|
| |
| Sistemas baseados no Cortex-M3 devem ter um mapa de memória definido:
| |
|
| |
| <table border=1>
| |
| <tr><td>0xFFFFFFFF<BR>
| |
| 0xE0000000</td><td>Periféricos do sistema: NVIC, debug
| |
| </td></tr>
| |
| <tr><td>
| |
| 0xDFFFFFFF<br>
| |
| 0xA0000000
| |
| </td><td>Livre para Perifé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éricos definidos pelo fabricante do CHIP
| |
| </td></tr>
| |
| <tr><td>
| |
| 0x3FFFFFFF<br>
| |
| 0x20000000</td>
| |
| <td>SRAM (Memória integrada no CHIP)
| |
| </td></tr>
| |
| <tr><td>
| |
| 0x1FFFFFFF<br>
| |
| 0x00000000</td>
| |
| <td>Memó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 à ULA.
| |
| Algumas instruções THUMB só podem acessar os registradores de R0 a R7.
| |
|
| |
| Tres registradores tem propósito especial:
| |
|
| |
| <dl>
| |
| <dt>R0 a R7 <dd> Registradores do usuário baixos: Todas as instruções tem acesso.
| |
| <dt>R8 a R12 <dd> Registradores do usuário altos: Algumas instruções THUMB não tem acesso.
| |
| <dt>R13 ou SP <dd>Stack Pointer. Apontador de pilha. Existem dois apontadores de pilha, ambos acessíveis como R3:
| |
| <ul><li><b>MSP</b> Main Stack Pointer: Este é o apontador de pilha principal, usado no núcleo do sistema operacional
| |
| e no tratamento de exceções.</li>
| |
| <li><b>PSP</b> Process Stack Pointer: Usada em programas aplicativos (modo usuário).
| |
| </ul>
| |
|
| |
| As intruçõ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çõ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é o endereço de retorno para chamadas de subrotina.
| |
| A instrução BL <i><endereço ></i> funciona como uma chamada de subrotina.
| |
| Ela salva automaticamete o endereço da
| |
| intrução seuinte no LR e salta para o local indicado pelo operando.
| |
| Se for necessá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ço da próxima instrução
| |
| que será 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ções</li>
| |
| <li> CONTROL: Indica o modo de operação: Privilegiado, Usuário ou executando uma excessão</li>
| |
| </ul>
| |
|
| |
|
| |
| Os bits NZCV do xPSR são chamados <i>"Condition Code"</i> abreviado como <i>cc</i>.
| |
|
| |
| Em geral, os códigos cc refletem o resultado da última instrução da unidade aritmética.
| |
|
| |
| <b>N</b> <i>Negative:</i> É uma cópia do bit mais significativo do resultado, que indica o
| |
| sinal. Resultado com bit mais significativo 1 é 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 última operaçã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éstimo na subtraçã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ção com sinal. Ocorre quando mudou o sinal
| |
| sem a ativaçã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ções tem um campo que permite a sua execução condicional de acordo
| |
| com o estado dos bits NZCV do xPSR. Na linguagem assembly esta execução condicional é
| |
| indicada por um sufixo de duas letras no mnemonico da instrução de acordo com a tabela a seguir:
| |
|
| |
| <table border=0 cellpadding=8><tr><td>
| |
| <table border=1>
| |
| <tr><th>cc</th><th>Condiçã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ção</th>
| |
| <tr><td>CC</td><td>C=0 Carry Clear</td></tr>
| |
| <tr><td>NE</td><td>Z=0 Not Equal (nã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ções pode afetar ou não os indicadores de estado no CPSR.
| |
| Na linguagem assembly coloca-se um sufixo com a letra <b>s</b> no mnemonico da instruçã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 & 7 Quado tem 2 operandos o destino=primeiro op */
| |
| </pre>
| |
|
| |
| As instruções de processamento de dados geralmente tem 3 argumentos:
| |
|
| |
| <ul><li>op1: O primeiro argumento é um registrador onde o resultado é armazenado</li>
| |
| <li>op2: O segundo argumento é um registrador usado como primeiro operando da operação</li>
| |
| <li>op3: O terceiro argumento é o segundo operando da operação, que pode ser um valor imediato de 8 bits,
| |
| um registrador ou um registrador com deslocamento.</li>
| |
| </ul>
| |
|
| |
|
| |
| As instruções de 3 argumentos são as seguintes:
| |
|
| |
| <table border=1>
| |
| <tr><th colspan=3>instruções de 3 argumentos</th></tr>
| |
| <tr><td>AND op1,op2,op3</td><td>op1 = op2 & 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ção</td></tr>
| |
| <tr><td>RSB op1,op2,op3</td><td>op1 = op3 - op2</td><td>Subtraçã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ção com carry</td></tr>
| |
| <tr><td>RSC op1,op2,op3</td><td>op1 = op3 - op2</td><td>Subtraçã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 & ~op3</td><td>Bit clear (zera bits)</td></tr>
| |
| </table>
| |
|
| |
| Nas instruçõ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ções de 3 operandos:===
| |
|
| |
| <pre class=code>
| |
| ORR R1, R2, #0x20 @ R1 = R2 | 0x20
| |
| ADD R2, R3, R4, LSL #3 @ R2 = R3 + (R4 << 3)
| |
| RSB R4, R5, #0 @ R5 = 0 - R5
| |
| SUB R1, R2, R3, LSR R4 @ R1 = R2 - (R3 >> R4)
| |
| </pre>
| |
|
| |
| <table border=1>
| |
| <tr><th colspan=3>instruçõ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 & 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ções de leitura da memória===
| |
|
| |
|
| |
| Nesta listagem Rd e Re podem ser registradores R0 a R15.
| |
|
| |
| Rd é o registrador que recebe o valor lido da memória; Re é o reg que contém o endereço de
| |
| memória que será lido. <tt>offset</tt> é uma constante positiva ou negaiva de 12 bits usada
| |
| para modificar o endereço.
| |
|
| |
| <table border=1>
| |
| <tr><th colspan=3>Instruções de leitura da Memória para Registrador</th></tr>
| |
| <tr><td>LDR Rd,[Re, #offset]</td><td> Rd := memória[Re + offset]; </td><td>Le 32 bits</td></tr>
| |
| <tr><td>LDRH Rd,[Re, #offset]</td><td> Rd := memória[Re + offset]; </td><td>Le 16 bits (Half word)</td></tr>
| |
| <tr><td>LDRB Rd,[Re, #offset]</td><td> Rd := memória[Re + offset]; </td><td>Le 8 bits (Byte)</td></tr>
| |
| <tr><td>LDR Rd,[Re, #offset]!</td><td> Rd := memó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ória[Re + Ri]</td><td>Le memória com endereço formdo
| |
| pela soma de 2 registradores</td></tr>
| |
| <tr><td>LDR Rd,[Re], #offset</td><td> Rd := memória[Re];<br>Re := Re + offset; </td><td>Le 32 bits
| |
| e modifica Re com pós incremento</td></tr>
| |
| </table>
| |
|
| |
| ===Instruções de escrita na memória===
| |
|
| |
|
| |
| Nesta listagem Rf e Re podem ser registradores R0 a R15.
| |
|
| |
| Rf é o registrador que será armazenado na memória; Re é o reg que contém o endereço na
| |
| memória. <tt>offset</tt> é uma constante positiva ou negaiva de 12 bits usada
| |
| para modificar o endereço.
| |
| <table border=1>
| |
| <tr><th colspan=3>Instruções escrita de Registrador na Memória</th></tr>
| |
| <tr><td>STR Rf,[Re, #offset]</td><td> memória[Re + offset]:= Rf; </td><td>Escreve 32 bits</td></tr>
| |
| <tr><td>STRH Rf,[Re, #offset]</td><td> memória[Re + offset]:= Rf; </td><td>Escreve 16 bits (Half word)</td></tr>
| |
| <tr><td>STRB Rf,[Re, #offset]</td><td> memória[Re + offset]:= Rf; </td><td>Escreve 8 bits (Byte)</td></tr>
| |
| <tr><td>STR Rf,[Re, #offset]!</td><td> memó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ória[Re]:= Rf;<br>Re := Re + offset; </td><td>Escreve 32 bits
| |
| e modifica Re com pós incremento</td></tr>
| |
| </table>
| |
|
| |
| ===Instruçõ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ção <tt>BL</tt> salva o endereço de retorno no R14 (que é 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ções da subrotina
| |
| MOV PC,LR @ Retorna da subrotina
| |
| </pre>
| |
|
| |
| O método acima não é aninhável. Nã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ções da subrotina
| |
| POP {R1, R2, PC} @ Restaura R1 e R2 e retorna da subrotina
| |
| </pre>
| |
|
| |
|
| |
|
| |
| -----------
| |
| =Aplicativo VISUAL (Arm)=
| |
|
| |
| Disponível para download em: [https://salmanarif.bitbucket.io/visual/downloads.html Visual - IDE para programação ARM]
| |
|
| |
| Lista de instruções suportadas: [https://salmanarif.bitbucket.io/visual/supported_instructions.html INSTRUÇÕES ARM para Visual]
| |
|
| |
| =Aplicativo ArmSim=
| |
|
| |
| Disponível para download em: [https://webhome.cs.uvic.ca/~nigelh/ARMSim-V2.1/Windows/index.html ARMSim - IDE para programação ARM]
| |
|
| |
| =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 > ]] |
| |} | | |} |