ÍNDICE DE CONTEÚDO
- Arquitetura de Conjunto de Instruções MIPS
- Primeira Instrução MIPS
- Compilação de Expressões no MIPS
- Convertendo uma instrução com Array no MIPS
- Armazenando um valor em Array no MIPS
- Instruções LW e SW com Array no MIPS
- Instrução IF Simples no MIPS
- Instrução IF Composto no MIPS
- Instrução SLT no MIPS
- Operações Lógicas no MIPS
- Operação Lógica AND no MIPS
- Operação Lógica OR no MIPS
- Operação Lógica NOT no MIPS
- Endereços de Memória no MIPS
- Operandos Imediatos e Constantes no MIPS
- Compilando Arrays com índice variável no MIPS
- Testando as instruções MIPS no MARS
- Executando um Array no MARS para MIPS
- Sinal e Overflow no MIPS
- Compilando instruções com ou sem Sinal, Overflow e Imediato no MIPS
- Compilando While no MIPS
- Compilando Switch/Case no MIPS
- Compilando Funções e Procedimentos no MIPS
- Compilando Procedimentos Recursivos e Aninhados no MIPS
- Detalhamento da Compilação de Procedimentos no MIPS
- MIPS: Instruções de Multiplicação
- MIPS: Instruções de Divisão
- MIPS: Subtração e outras instruções
- Compilando o comando FOR no MIPS
- Ponto Flutuante no MIPS
- Convertendo Código de Máquina em Assembly MIPS – Parte 1
- MIPS: Resolução dos exercícios – Parte 1
- MIPS: Resolução de Exercícios Parte 2
- Compilando Potência no MIPS
- Criando e Manipulando Matrizes no MIPS
Oi pessoal!!!! Tudo bem com todos? Espero que sim. Hoje darei continuidade às operações que podemos realizar com o conjunto de instruções MIPS. Já vimos algumas instruções para operações aritméticas, salto e transferência de dados, hoje vamos aprender um pouco sobre as operações lógicas no MIPS! Partiu então?
Operações Lógicas
Cinco são as operações lógicas definidas no MIPS, conforme mostra a Tabela 1:
Tabela1: Operações Lógicas MIPS
Operações Lógicas | Instruções MIPS |
Shift à direita | SLL |
Shift à esquerda | SRL |
And bit a bit | AND, ANDI |
Or bit a bit | OR, ORI |
Not bit a bit | NOR |
As instruções de operações lógicas ajudam a simplificar o empacotamento e o desempacotamento dos bits em words. Todos lembram o que é uma word? Sim? Não? Vale a pena relembrar né? A unidade de informação que trabalhamos em máquinas digitais, como a grande maioria já deve saber, são os bits, isto é, os zeros e uns. Quando os zeros e uns são agrupados em uma determinada quantidade eles recebem nomes, conforme mostra a Tabela 2:
Tabela 2: Bits
Bit | 1 bits | 0 |
Nibble | 4 bits | 0000 |
Byte | 8 bits | 0000 0000 |
Word | 16 bits | 0000 0000 0000 0000 |
Double Word | 32 bits | 0000 0000 0000 0000 0000 0000 0000 0000 |
Quad Word | 64 bits | 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 |
Um bit é correspondente a um único bit, isto é, ou ele tem o valor zero, ou tem o valor um, um nibble corresponde a 4 bits, um byte são 8 bits, e assim, consecutivamente, até chegarmos no número de bits máximo.
A Tabela 2 apresenta Word como uma quantidade de 16 bits, entretanto, Word é usada atualmente como sinônimo de PALAVRA. Uma Word (ou Palavra) é a quantidade de bits que se consegue transmitir, portanto, não é obrigatoriamente 16 bits, pode ser 32 bits. Esclarecida esta questão, vamos estudar agora a operação SHIFT e, nos artigos posteriores, veremos as outras operações.
Operação SHIFT
Shift significa deslocamento, assim um shift à esquerda significa um deslocamento à esquerda e, um shift à direita, significa um deslocamento à direita. Mas, você está aí se perguntando: “ora, bolas, carambolas, deslocamento de quem?”. Pois bem, é o deslocamento dos bits da palavra. Os shifts movem todos os bits de uma palavra, preenchendo os bits que ficaram vazios com zeros. Vamos ver um exemplo para entender melhor. Suponha que um registrador tivesse armazenado o valor 9:
0000 0000 0000 0000 0000 0000 1001
Agora imagine que é executada uma instrução de deslocamento que comanda o deslocamento de 4 bits à esquerda. O novo valor desse registrador será:
0000 0000 0000 0000 0000 1001 0000
Conseguiram notar a diferença? Agora o valor não é mais o 9, mas sim 144. Portanto, ao realizarmos o deslocamento de 4 bits à esquerda, mudamos o valor decimal que estava armazenado no registrador também.
SLL significa Shift Left Logical (deslocamento lógico à esquerda) e SRL significa Shift Right Logical (deslocamento lógico à direita), que são os mnemônicos e nomes das instruções MIPS. Assim, o exemplo acima fica da seguinte forma na linguagem de montagem:
SLL $t2, $s0, 4 # $t2 = $s0 << 4 bits
A linguagem de máquina fica da seguinte forma:
SLL $10, $16, 4
A representação fica assim:
opcode | rs | rt | rd | shamt | funct |
0 | 0 | 16 | 10 | 4 | 0 |
6 bit | 5 bits | 5 bits | 5 bits | 5 bits | 6 bits |
Para finalizar a compilação, o código da máquina:
000000 00000 10000 01010 00100 000000
Assim, 4 é o número de bits que deve ser deslocado, portanto, ele deve ser colocado no campo SHAMT, que significa Shift Amount. Esse campo armazena a quantidade de deslocamento e é usado apenas para instruções de deslocamento. $t2 ($10) é o registrador que armazenará o resultado, portanto, registrador destino e, por isso, é colocado no campo RD. $s0 ($16) deve ser inserido no campo RT. O campo RS não é utilizado, por isso colocamos zero. A codificação padrão para SLL é zero pra o campo de código e para funct. Portanto, SLL é uma instrução do tipo R.
Em nosso exemplo o número decimal inicial era 9 e o resultado do deslocamento em 4 bits foi 144. Se vocês fizerem 9 x 24 o resultado será 144, ou seja, a instrução SLL é equivalente a uma multiplicação por 2i.
A instrução SRL é muito parecida com a SLL, a diferença básica é que a SRL desloca os bits para a direita. O código de FUNCT para SLL é 2 e o opcode é 0. Vejamos um exemplo:
0000 0000 0000 0000 0000 1001 0000 = 14410
Deslocando 4 bits a direita:
0000 0000 0000 0000 0000 0000 1001 = 910
Assim a instrução na linguagem de montagem fica da seguinte forma:
SRL $t2, $s0, 4 # $t2 = $s0 >> 4 bits
Na linguagem de máquina fica:
SRL $10, $16, 4
A representação fica da seguinte forma:
opcode | rs | rt | rd | shamt | funct |
0 | 0 | 16 | 10 | 4 | 2 |
6 bit | 5 bits | 5 bits | 5 bits | 5 bits | 6 bits |
Finalizando a compilação, o código de máquina:
000000 00000 10000 01010 00100 000010
Conclusão
Acharam muito dificil? Ou acharam divertido? Estão um pouco perdidos ainda? Não se preocupem, estou disponível para tirar todas as suas dúvidas, basta deixá-las ali nos comentários. Deixarei alguns exercícios para vocês praticarem. Lembrem-se: é importante ler todos os artigos anteriores pois estou os escrevendo em uma ordem para facilitar a aprendizagem. Ao final deste artigo coloquei um tópico chamado RECAPITULANDO, que contém um resumo de todas as instruções que já estudamos até este artigo. Então, está combinado? Fechou? Até a próxima.
Exercícios
Considere os seguintes números decimais:
- 10
- 25
- 43
- 89
- Faça a compilação do deslocamento à direita em 8 bits para cada um deles.
- Faça a compilação do deslocamento à esquerda em 4 bits para cada um deles.
Recapitulando
Registradores
Tabela 1: Os 32 Registradores de uso geral do MIPS 32 bits.
Nome do Registrador | Número | Binário | Uso |
$zero | 0 | 000 000 | constante zero |
$at | 1 | 000 001 | reservado para o montador |
$v0 | 2 | 000 010 | avaliação de expressão e resultados de uma função |
$v1 | 3 | 000 011 | avaliação de expressão e resultados de uma função |
$a0 | 4 | 000 100 | argumento 1 (passam argumentos para as rotinas) |
$a1 | 5 | 000 101 | argumento 2 |
$a2 | 6 | 000 110 | argumento 3 |
$a3 | 7 | 000 111 | argumento 4 |
$t0 | 8 | 001 000 | temporário (valores que não precisam ser preservados entre chamadas) |
$t1 | 9 | 001 001 | temporário |
$t2 | 10 | 001 010 | temporário |
$t3 | 11 | 001 011 | temporário |
$t4 | 12 | 001 100 | temporário |
$t5 | 13 | 001 101 | temporário |
$t6 | 14 | 001 110 | temporário |
$t7 | 15 | 001 111 | temporário |
$s0 | 16 | 010 000 | temporário salvo (valores de longa duração e devem ser preservados entre chamadas) |
$s1 | 17 | 010 001 | temporário salvo |
$s2 | 18 | 010 010 | temporário salvo |
$s3 | 19 | 010 011 | temporário salvo |
$s4 | 20 | 010 100 | temporário salvo |
$s5 | 21 | 010 101 | temporário salvo |
$s6 | 22 | 010 110 | temporário salvo |
$s7 | 23 | 010 111 | temporário salvo |
$t8 | 24 | 011 000 | temporário |
$t9 | 25 | 011 001 | temporário |
$k0 | 26 | 011 010 | reservado para o Kernel do sistema operacional |
$k1 | 27 | 011 011 | reservado para o Kernel do sistema operacional |
$gp | 28 | 011 100 | ponteiro para área global |
$sp | 29 | 011 101 | stack pointer (aponta para o último local da pilha) |
$fp | 30 | 011 110 | frame pointer (aponta para a primeira palavra do frame de pilha do procedimento) |
$ra | 31 | 011 111 | endereço de retorno de uma chamada de procedimento |
Formato das Instruções
Tabela 2: Formato de Instrução do Tipo R
op | rs | rt | rd | shamt | funct |
6 bits | 5 bits | 5 bits | 5 bits | 5 bits | 6 bits |
opcode ou código da operação | registrador do primeiro operando fonte | registrador do segundo operando fonte | registrador do operando destino | deslocamento |
função de operação ou código de função |
Tabela 3: Representação de Instruções do Formato Tipo I
opcode | rs | rt | endereço |
6 bits | 5 bits | 5 bits | 16 bits |
código de operação | registrador destino | registrador fonte | endereço de memória |
Tabela 4: Representação de Instruções do Formato Tipo J
opcode | endereço |
6 bits | 26 bits |
código de operação | endereço de memória do salto |
OPCODES
Tabela 5: Opcodes
OPCODE | DECIMAL | BINÁRIO |
ADD | 32 | 100 000 |
SUB | 34 | 100 010 |
OR | 36 | 100 100 |
AND | 37 | 100 101 |
SLT | 42 | 101 010 |
BNE | 4 | 000 100 |
BEQ | 5 | 000 101 |
J | 2 | 000 010 |
JR | 8 | 001 000 |
LW | 35 | 100 011 |
SW | 43 | 101 011 |
SRL | 0 | 000 000 |
SLL | 0 | 000 000 |
Linguagem Assembly
Aritméticas
- Formato R
Sintaxe | Exemplo | |
Soma | add registrador_destino, registrador_fonte, registrador_fonte | add $t1, $s0, $s1 |
Subtração | sub registrador_destino, registrador_fonte, registrador_fonte | sub $t2, $s2, $s3 |
Shift à direita | srl registrador_destino, registrador_fonte, deslocamento | srl $t0, $s1, 5 |
Shift à esquerda | sll registrador_destino, registrador_fonte, deslocamento | sll $t0, $s1, 5 |
Transferências de dados
- Formato I
Sintaxe | Exemplo | ||
Memória para Registrador | lw registrador_destino, endereço, registrador_fonte | lw $s1, 20 ( $s2 ) | $s1 = Memória [ $s2 + 20 ] |
Registrador para Memória | sw registrador_fonte, endereço, registrador_destino | sw $s1, 20 ( $s2 ) | Memória [ $s2 + 20 ] = $s1 |
Desvios Condicionais
- Formato R
Sintaxe | Exemplo | ||
Desvie se Igual (Teste de Igualdade) | beq registrador_fonte1, registrador_fonte2, label | beq $s1, $s2, label |
se ($s1 = $s2) vá para o label |
Desvie se não for Igual (Teste de desigualdade) | bne registrador_fonte1, registrador_fonte2, label | bne $s1, $s2, label | se ($s1 != $s2) vá para o label |
Setar se menor que | slt registrador_destino, registrador_fonte1, registrador_fonte2 | slt $s1, $s2, $s32 |
se ($s2 < $s3) então $s1 = 1 senão $s1 = 0 |
Desvios Incondicionais
- Formato J
Sintaxe | Exemplo | |
Salto | j endereço_de_memória | j 25000 |
Conceitos Importantes
Conjunto de Instruções: é o vocabulário dos comandos entendidos por uma determinada arquitetura.
Conceito de Programa Armazenado: é a ideia de que as instruções e os dados de muitos tipos podem ser armazenados na memória como números, levando ao computador de programa armazenado.
Instrução de Transferência de memória: é um comando que move dados entre a memória e os registradores.
Endereço: é um valor usado para delinear o local de um elemento de dados específico dentro de uma sequência da memória.
Palavra (Word): é a unidade de acesso natural de um computador, normalmente um grupo de 32 bits, corresponde ao tamanho de um registrador na arquitetura MIPS.
Eliane,
Parabéns , muito bem explicado. Estou tendo Arquitetura de Computadores nesse semestre na faculdade e vai ajudar bastante.
Que bom Andre! Precisando entre em contato.