Oi pessoal! No artigo anterior eu detalhei a Compilação de Procedimentos no MIPS. No artigo de hoje, vou falar sobre algumas instruções que ainda não foram apresentadas a vocês. Quem tiver interesse, todas as informações referentes à Arquitetura MIPS estão disponíveis no site oficial neste link: https://www.mips.com.
Multiplicação
MULT: Multiply Word
Sintaxe: mult rs, rt
Formato:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
0 |
|
0x18 | |||
|
6 bits |
5 bits |
5 bits |
10 bits |
6 bits |
A multiplicação “normal”, vamos assim dizer, é parecida com as instruções que já estudamos até aqui. A diferença agora está nos 10 bits que compreendem os campos rd e shamt. Vamos fazer a multiplicação entre os números 10 e 2. Manualmente sabemos que o resultado é 20. Agora vamos converter todos os números para binário e em seguida para hexadecimal:
10 = 0000 1010 = A
2 = 0000 0010 = 2
20 = 0001 0100 = 14
Isso vai nos ajudar a nos localizar no simulador MARS. O código para testar esta instrução é dado abaixo:
.text li $s2, 10 #carrega o valor imediato 10 no registrador s2 (li = load immediate) li $s3, 2 #carrega o valor imediato2 no registrador s3 mult $s2, $s3 #executa a multiplicação entre s2 e s3
Execute este código no MARS. Você verá algo como as imagens abaixo. Note que o resultado da multiplicação é armazenada no registrador lo, que é o registrador que armazena a palavra menos significativa do produto. A palavra mais significativa do produto é armazenada no registrador hi.
Multiplicação sem sinal
MULTU: Multiply Unsigned Word
Sintaxe: multu rs, rt
Formato:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
0 |
|
0x19 | |||
|
6 bits |
5 bits |
5 bits |
10 bits |
6 bits |
A diferença desta multiplicação para a anterior, é que nesta o sinal do número não é considerado (sem sinal). Da mesma forma que MULT, aqui os registradores HI e LO também são utilizados. Note também que o código em FUNCT é outro. Tome muito cuidado, pois esses códigos são muito parecidos. Quando for programar, caso tenha dúvidas, consulte sempre os artigos disponíveis no Embarcados. Para facilitar nosso entendimento, vamos usar os mesmos números para todos os exemplos.
.text li $s2, 10 #carrega o valor imediato 10 no registrador s2 (li = load immediate) li $s3, 2 #carrega o valor imediato2 no registrador s3 mult $s2, $s3 #executa a multiplicação entre s2 e s3
Multiplicação sem overflow
MUL: Multiply Word to GPR (register propouse geral)
Sintaxe: mul rd, rs, rt
Formato:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
0x1c |
|
0 |
2 | ||
|
6 bits |
5 bits |
5 bits |
5 bits |
5 bits |
6 bits |
Esta multiplicação não trata do overflow, e é parecida com a instrução ADD que conhecemos. O resultado da multiplicação será armazenado no registrador RD. No caso do nosso exemplo, RD será o registrador $s1
.text li $s2, 10 #carrega o valor IMEDIATO 10 no registrador s2 (li = load immediate) li $s3, 2 #carrega o valor IMEDIATO 2 no registrador s3 mul $s1 $s2, $s3 #executa a multiplicação entre s2 e s3 e armazena o resultado em $s1
Multiplicação com overflow
Sintaxe: mulo r_destino, r_source1, r_source2
Esta multiplicação é uma pseudoinstrução, isto significa que ela desencadeia uma série de outras instruções em sua execução. Para entende-la vamos ver em detalhes a execução do código abaixo no MARS.
.text li $s2, 10 #carrega o valor IMEDIATO 10 no registrador s2 (li = load immediate) li $s3, 2 #carrega o valor IMEDIATO 2 no registrador s3 mulo $s1 $s2, $s3 #executa a multiplicação entre s2 e s3 e armazena o resultado em $s1
Observe a imagem:
A primeira e a segunda linha são instruções que já conhecemos e discutimos anteriormente. A terceira linha realiza uma instrução MULT, que é a multiplicação normal que vimos neste artigo. Note que o registrador LO e HI tem os valores 14 e 0 respectivamente. Na quarta linha temos a instrução MFHI, que significa Move From HI register e tem a seguinte sintaxe:
mfhi rd
O formato é:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
0 |
|
|
010000 | ||
|
6 bits |
10 bits |
5 bits |
5 bits |
6 bits |
Esta instrução copia o valor do registrador HI para RD. Em nosso exemplo, HI tem o valor zero e será copiado para $1. Já na quinta linha, encontra-se a instrução MFLO, que é idêntica à instrução MFHI, a qual copia o valor do registrador lo para o registrador RD. Em nosso exemplo, LO vale 14 e este será copiado para o registrador $17.
Sintaxe: mflo rd
Formato:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
0 |
|
|
010010 | ||
|
6 bits |
10 bits |
5 bits |
5 bits |
6 bits |
Na sexta linha vemos a instrução SRA (Shift Word Right Arithmetic), que executa um deslocamento aritmético à direita, de uma palavra, por um número fixo de bits. A sintaxe é o seguinte:
sra rd, rt, sa
E o formato é:
|
opcode |
rs |
rt |
rd |
sa |
funct |
|
0 |
|
|
|
000011 | |
|
6 bits |
5 bits |
5 bits |
5 bits |
5 bits |
6 bits |
O conteúdo da palavra de 32 bits de baixa ordem do registrador de uso geral é deslocado para a direita, duplicando o bit de sinal (bit 31) nos bits esvaziados. O resultado da palavra é colocado no registrador RD, e o valor do deslocamento de bits é especificado por SA. Em nosso exemplo, a instrução está da seguinte maneira:
sra $17, $17, 0x0000001f
$17 tem o valor 14 e é nosso registrador RD, e o valor 0x0000001f é o valor de deslocamento. A próxima linha possui a instrução BEQ, a qual já estudamos anteriormente, e está da seguinte forma:
Beq $1, $17, 0x00000001
Portanto, se $1 = $17, desviará para o endereço 0x00000001. Tudo é necessário para tratar do overflow, que já foi explicado no artigo “Sinal e Overflow no MIPS”. Na linha 8 temos a palavra-chave break, para parar a execução, e na linha 9 a instrução MFLO $17, que conterá o resultado final da multiplicação.
Multiplicação sem sinal com overflow
Mulou r_destino, r_source1, r_source_2
Esta pseudoinstrução funcionará de forma parecida a instrução MULO. A instrução MULTU será utilizada no lugar da instrução MULT e não fará uso da instrução SRA. O código é dado a seguir:
.text li $s2, 10 #carrega o valor IMEDIATO 10 no registrador s2 (li = load immediate) li $s3, 2 #carrega o valor IMEDIATO 2 no registrador s3 madd $s2, $s3 #executa a multiplicação entre s2 e s3
Observe a imagem da execução no MARS:
Multiplicação Adição
MADD: Multiply and Add Word to Hi,Lo
Sintaxe: Madd, rs, rt
Formato:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
0x1c |
|
|
0 | ||
|
6 bits |
5 bits |
5 bits |
10 bits |
6 bits |
Exemplo de código:
.text li $s2, 10 #carrega o valor IMEDIATO 10 no registrador s2 (li = load immediate) li $s3, 2 #carrega o valor IMEDIATO 2 no registrador s3 madd $s2, $s3 #executa a multiplicação entre s2 e s3
O objetivo desta instrução é multiplicar duas palavras e adicionar o resultado a Hi, Lo. O valor da palavra de 32 bits em registrador rs é multiplicado pelo valor da palavra de 32 bits no registrador rt, produzindo um resultado de 64 bits. O produto é adicionado aos valores concatenados de 64 bits de HI e LO. Os 32 bits mais significativos do resultado são escritos em HI e os 32 bits menos significativos são gravados em LO.
Multiplicação adição sem sinal
MADDU: Multiply and Add Unsigned Word to Hi, Lo.
Sintaxe: Maddu rs, rt
Formato:
|
opcode |
rs |
rt |
rd |
sa |
funct |
|
0x1c |
|
|
|
1 | |
|
6 bits |
5 bits |
5 bits |
5 bits |
5 bits |
6 bits |
Exemplo de código:
.text li $s2, 10 #carrega o valor IMEDIATO 10 no registrador s2 (li = load immediate) li $s3, 2 #carrega o valor IMEDIATO 2 no registrador s3 maddu $s2, $s3 #executa a multiplicação entre s2 e s3
Essa instrução multiplica duas palavras sem sinal e adiciona o resultado em HI e LO. O valor da palavra de 32 bits no registrador rs é multiplicado pelo valor da palavra de 32 bits no registrador rt, produzindo um resultado de 64 bits. O produto é adicionado aos valores concatenados de 64 bits de HI e LO. Os 32 bits mais significativos do resultado são escritos em HI e os 32 bits menos significativos são gravados em LO.
Multiplicação Subtração
MSUB: Multiply and Subtract Word to Hi,Lo
Sintaxe: msub rs, rt
Formato:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
01xc |
|
|
4 | ||
|
6 bits |
5 bits |
5 bits |
10 bits |
6 bits |
Exemplo de código:
.text li $s2, 10 #carrega o valor IMEDIATO 10 no registrador s2 (li = load immediate) li $s3, 2 #carrega o valor IMEDIATO 2 no registrador s3 msub $s2, $s3 #executa a multiplicação entre s2 e s3
A instrução multiplica duas palavras e subtrai o resultado de HI, LO. O valor da palavra de 32 bits no registrador RS é multiplicado pelo valor de 32 bits no registrador RT, produzindo um resultado de 64 bits. O produto é subtraído dos valores concatenados de 64 bits de HI e LO. Os 32 bits mais significativos do resultado são escritos em HI e os 32 bits menos significativos são gravados em LO.
Multiplicação Subtração Sem Sinal
MSUB: Multiply and Subtract Word to Hi,Lo
Sintaxe: msub rs, rt
Formato:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
01xc |
|
|
5 | ||
|
6 bits |
5 bits |
5 bits |
10 bits |
6 bits |
Exemplo de código:
.text li $s2, 10 #carrega o valor IMEDIATO 10 no registrador s2 (li = load immediate) li $s3, 2 #carrega o valor IMEDIATO 2 no registrador s3 msub $s2, $s3 #executa a multiplicação entre s2 e s3
A instrução é exatamente a mesma da anterior, porém, o código de função é 5 e não 4! Fique atento. Esta instrução multiplica duas palavras e subtrai o resultado de HI, LO. O valor da palavra de 32 bits no registrador RS é multiplicado pelo valor de 32 bits no registrador RT produzindo um resultado de 64 bits. O produto é subtraído dos valores concatenados de 64 bits de HI e LO. Os 32 bits mais significativos do resultado são escritos em HI e os 32 bits menos significativos são gravados em LO.
Por hoje é só pessoal! No próximo artigo, vamos conhecer outras instruções! Até.












