Í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
No artigo anterior nós vimos como converter uma expressão matemática em Linguagem C que tinha parênteses. Hoje vamos aprender como converter uma instrução com Array no MIPS.
Como exemplo, suponha a seguinte instrução em linguagem C:
a = b + c[10];
Vamos usar o registrador $s0 para a variável a, $s1 para variável b e $s2 para a variável c. c é um vetor e não sabemos quantas posições ele tem, só sabemos que iremos somar o valor da variável b com o valor que está armazenado na posição 10 do vetor c. Bom, pra podermos fazer a conversão dessa instrução introduzirei uma nova instrução que também é de um tipo diferente do que já vimos até aqui.
Instruções de Formato Tipo I
As instruções de formato Tipo I têm menos campos que as instruções do formato tipo R (aritméticas), mas ainda tem 32 bits, não vamos nos esquecer de que no MIPS todas as instruções tem exatamente o mesmo tamanho em bits, ok?! A instrução de formato Tipo I é representada na Tabela 1 e normalmente são classificadas como instruções de transferência de dados.
Tabela 1: 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 |
O primeiro campo, OPCODE, é o código da operação e tem 6 bits; o segundo campo, RS, é o registrador destino e tem tamanho 5 bits; o terceiro campo, RT, é o registrador fonte e tem tamanho 5 bits; e o quarto campo, ENDEREÇO, é o endereço de memória que tem 16 bits.
Load Word (LW) e Store Word (SW) são duas instruções de transferência de dados, do formato I, e hoje vamos aprender a usar a LW.
LOAD WORD
Essa instrução transfere dados da memória para os registradores e, sempre que tivermos um Array, deveremos utilizá-la pois, antes de manipularmos o valor de uma determinada posição do Array, devemos tê-lo disponível para isso. Sua sintaxe é a seguinte:
LW registrador_destino, valor (registrador_fonte)
Exemplo:
LW $t0, 30 ( $s0 ) # $t0 = memória [ $s0 + 30 ]
O registrador $t0 receberá o valor que está no endereço de memória que é calculado pela própria instrução: $s0 + 30. Então, toda vez que você usar a instrução LW, você está transferindo para um registrador, um valor que está no endereço de memória calculado pela soma do registrador fonte com um valor. Neste exemplo é um valor dado (30), ou seja, é a posição 30 do Vetor que aqui é representado por $s0. Mais pra frente veremos como fazer isso sem usar um valor específico.
Compilação de uma atribuição com um operando na memória
Agora que já fomos apresentados às instruções de formato TIPO I e também à instrução LW, vamos ver como fica a conversão da nossa instrução. O primeiro passo é converter c[10] que ficará assim:
LW $t0, 10 ($s2) # $t0 = memória [ $s2 + 10 ]
Observe que $s2 é o vetor c, 10 é a posição do Vetor e $t0 é um registrador temporário que armazenará o valor que está em c[10]. O segundo passo é fazer b + c[10]:
ADD $s0, $s1, $t0 # $s0 = $s1 + $t0
Em que $t0 é o valor de c[10], $s0 é a variável a e $s1 é a variável b. Assim, o código final para a = b + c [10] fica da seguinte forma:
LW $t0, 10 ( $s2 )
ADD $s0, $s1, $t0
Observe também que uma instrução da linguagem C foi convertida em duas instruções para linguagem MIPS.
Linguagem de Máquina
A Linguagem de Máquina para a = b + c [ 10 ] ficará da seguinte forma:
LW $8, 10 ( $18 )
ADD $16, $17, $8
Representação da Linguagem de Máquina
A representação da linguagem de máquina para a = b + c [ 10 ] ficará da seguinte forma:
opcode | rs | rt | rd | shamt | funct |
35 | 8 | 18 | 10 | ||
0 | 17 | 8 | 16 | 0 | 32 |
Código de Máquina
O código de máquina para a = b + c [ 10 ] ficará da seguinte forma:
opcode | rs | rt | rd | shamt | funct |
100 011 | 01000 | 10010 | 0000 0000 0000 1010 | ||
000 000 | 10001 | 01000 | 10000 | 00000 | 100 000 |
10001101000100100000000000001010
00000010001010001000000000100000
Resumo
Formato Tipo R
opcode | rs | rt | rd | shamt | funct |
6 bits | 5 bits | 5 bits | 5 bits | 5 bits | 6 bits |
código da operação | registrador fonte | registrador fonte | registrador destino | deslocamento | sub código da operação |
Formato Tipo I
opcode | rs | rt | endereço |
6 bits | 5 bits | 5 bits | 16 bits |
código da operação | registrador destino | registrador fonte | endereço de memória |
Instruções
Tipo R:
Instrução | Exemplo | |
ADD registrador destino, registrador fonte, registrador fonte | ADD $t0, $s0, $s1 | $t0 = $s0 + $s1 |
SUB registrador destino, registrador fonte, registrador fonte | SUB $t1, $s3, $s4 | $t1 = $s3 – $s4 |
Tipo I:
Instrução | Exemplo | |
LW registrador destino, valor ( registrador fonte) | LW $t0, 20 ( $s0 ) | $t0 = memória [ 20 + $s0 ] |
Exercícios
Converta as instruções abaixo:
- a = b[15] – c;
- b = a[5] + c[3];
- c = b – a[21];
Use $s0 para a, $s1 para b e $s2 para c.
Definitivamente o melhor conteúdo que encontrei sobre linguagem MIPS. Obrigada Elaine, vc não tem noção de como seu site me ajudou. Abraço!
Oi Rafaela, obrigada pelo seu comentário e desculpe pela demora pra responder. Ando bem ocupada com o doutorado. Fico mesmo muito feliz em ler isto! Meu objetivo é ajudar o maior número possível de estudantes com os conteúdos que publico aqui! Você não tem ideia do quão bom é saber que você é uma dessas alunas beneficiadas. [ ]s
Minhas respostas, procedem?
a.
lw $t0, 15($s1);
sub $s0, $t0, $s2;
b.
lw $t0, 5($s0);
lw $t1, 3($s2);
add $s1, $t0, $t1;
c.
lw $t0, 21($s0);
sub $s2, $s1, $t0;
Oi Márcio! Estou elaborando um artigo com as soluções tá bom. Obrigada.
Olá Elaine! Gostaria inicialmente de parabenizar pelo curso!! Muito didático, maravilhoso. Estou na dúvida se na parte que diz:
“O primeiro passo é converter c[10] que ficará assim:
LW $t0, 10 ($s2) # $t0 = memória [ $s2 + 10 ] “.
No caso não seria LW $t0, 40 ($s2) ?
Oi Queiroz. Esse cálculo eu ensino em outro artigo como fazer! Pra não ficar muito confuso e muita coisa pra explicar num único artigo ok! Obrigada pela participação.
Nem me atrevo a converter as instruções do exercício. Por enquanto…
A gente entende, mas tem que reviver o ou os artigos para fixar melhor o que entendeu.
É!!!!! Praticar sempre é o x da questão. Hoje eu entendo bem MIPS pq ministrei aulas desse conteúdo por quatro anos consecutivos, dai realmente fica mais fácil.
Gosto de praticar durante a noite no silêncio da madrugada. Não precisa ser, assim, na madrugada, mas a partir das 22 horas até umas 2 horas da madrugada é bem legal.
que bom!!!