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.