Oi pessoal! Tudo bem? No último artigo eu falei sobre o SINAL dos números e também sobre o OVERFLOW. Hoje vou apresentar a vocês algumas instruções que foram projetadas para lidar com isso. Vamos começar então?
Adição com Overflow – ADD
Esta operação aritmética nós já aprendermos, lá no terceiro artigo!
Adição sem Overflow – ADDU
Esta operação aritmética funciona praticamente da mesma forma que a Adição com Overflow, porém esta instrução não retém o overflow e, apenas a título de curiosidade, ADDU significa ADD Unsigned Word, isto é, traduzindo literalmente: Adição de Palavras Sem sinal. Esta operação é para módulos aritméticos de 32 bits que não são retidos no overflow, sendo apropriada para aritmética sem sinal, como a aritmética de endereços ou ambientes aritméticos inteiros que ignoram o overflow, como acontece na aritmética da linguagem C.
ADDU rd, rs, rt # rd = rs + rt
Exemplo:
ADDU $s0, $s1, $s2 # s0 = s1 + s2
Onde rd é o registrador destino, rs é o primeiro operando e rt é o segundo operando. O formato é o seguinte:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
0 |
|
|
|
0 |
(33)2 ou (0x21)16 |
|
6 bits |
5 bits |
5 bits |
5 bits |
5 bits |
6 bits |
Exemplo:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
0 |
$s1 |
$s2 |
$s0 |
0 |
33 |
|
0 |
17 |
18 |
16 |
0 |
33 |
|
000000 |
10001 |
10010 |
10000 |
00000 |
100001 |
Para testarmos essa instrução no Mars, devemos, antes de qualquer coisa, carregar valores para os registradores temporários e depois realizar a soma. Algo interessante a se falar aqui é que, ao usar o LI, o MARS mostra uma mensagem, explicando o tipo de imediato que será carregado de acordo com o imediato que você digitou, veja:
Traduzindo as mensagens (ao pé da letra praticamente):
li $t1, -100 define $t1 como um imediato de 16 bits com sinal estendido
li $t1, 100 define $t1 como um imediato de 16 bits sem sinal com zero estendido
li $t1, 10000 define $t1 como um imediato de 32 bits
Zero-extended, ou zero estendido, significa que os bits “não utilizados” de ordem mais alta são zeros. Bem, vamos testar então o nosso código com os seguintes valores:
|
$s1 |
$s2 |
$s0 |
|
-10 |
-15 |
(-10) + (-15) = -25 |
|
-10 |
+15 |
(-10) + (+15) = +5 |
|
+10 |
-15 |
(+10) + (-15) = -5 |
|
+10 |
+15 |
(+10) + (+15) = +25 |
|
-100 |
-150 |
(-100) + (-150) = -250 |
|
-100 |
+150 |
(-100) + (+150) = +50 |
|
+100 |
-150 |
(+100) + (-150) = -50 |
|
+100 |
+150 |
(+100) + (+150) = +250 |
|
-1.000 |
-1.500 |
(-1.000) + (-1.500) = -2.500 |
|
-1.000 |
+1.500 |
(-1.000) + (+1.500) = +500 |
|
+1.000 |
-1.500 |
(+1.000) + (-1.500) = -500 |
|
+1.000 |
+1.500 |
(+1.000) + (+1.500) = +2.500 |
|
-10.000 |
-15.000 |
(-10.000) + (-15.000) = -25.000 |
|
-10.000 |
+15.000 |
(-10.000) + (+15.000) = +5.000 |
|
-10.000 |
-15.000 |
(+10.000) + (-15.000) = -25.000 |
|
-10.000 |
+15.000 |
(+10.000) + (+15.000) = +5.000 |
Você fará o teste manualmente ok, nada de fazer um Array pra ir mais rápido, pois a intenção aqui é que você analise o que está acontecendo. Seguindo o código abaixo, você substituirá os valores em $s0 e $s1 conforme a tabela e a cada par de valores, vai executar o arquivo .asm, verificando os valores em hexadecimais e os estados dos registradores. Você vai perceber que quando o número é negativo (-), o “número” hexadecimal correspondente será F e, quando o número for positivo (+), zeros serão adicionados à esquerda.
.text li $s1, -10 #carrega o valor IMEDIATO -10 no registrador s1 li $s2, +15 #carrega o valor IMEDIATO +15 no registrador s2 ADDU $s0, $s1, $s2 #soma $s1 com $s2 e armazena o resultado em $s0
Adição com Imediato e com Overflow – ADDI
Esta instrução já foi estudada no 15.º artigo
Adição com Imediato e sem Overflow – ADDIU
Esta operação aritmética funciona praticamente da mesma forma que a Adição com Imediato e com Overflow, e significa Add Immediate Unsigned Word, ou Adição Imediata de Palavras sem Sinal. Esta operação é para módulos aritméticos de 32 bits que não são retidos no overflow, sendo apropriada para aritmética sem sinal, como na aritmética de endereços ou ambientes aritméticos inteiros que ignoram o overflow, como a aritmética da linguagem C.
ADDIU rt, rs, imm # rt = rs + imm
Exemplo:
ADDIU $s0, $s1, 20 # s0 = s1 + 20
Onde rd é o registrador destino, rs é o primeiro operando e rt é o segundo operando. O formato é o seguinte:
|
opcode |
rs |
rt |
imm |
|
9 |
|
|
|
|
6 bits |
5 bits |
5 bits |
16 bits |
Exemplo:
|
opcode |
rs |
rt |
imm |
|
9 |
16 |
17 |
20 |
|
001001 |
10000 |
10001 |
0000 0000 0001 0100 |
No Mars ficará da seguinte forma:
.text li $s1, -10000 #carrega o valor IMEDIATO no registrador s1 ADDIU $s0, $s1, 15000 #soma $s1 com $s2 e armazena o resultado em $s0
Mais uma vez aconselho a fazer o teste para a Tabela de valores apresentada em ADDU.
Subtração com Overflow – SUB
Esta operação aritmética nós já aprendermos, lá no terceiro artigo!
Subtração sem Overflow – SUBU
Esta operação aritmética funciona praticamente da mesma forma que a Subtração com Overflow, e significa Subtract Unsigned Word, ou Subtração de Palavras sem Sinal. Esta operação é para módulos aritméticos de 32 bits que não são retidos no overflow, sendo apropriada para aritmética sem sinal, como na aritmética de endereços ou ambientes aritméticos inteiros que ignoram o overflow, como a aritmética da linguagem C.
SUBU rt, rs, rt # rt = rs + rt
Exemplo:
SUBU $s0, $s1, $s2 # s0 = s1 + s2
Onde rd é o registrador destino, rs é o primeiro operando e rt é o segundo operando. O formato é o seguinte:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
0 |
|
|
|
0 |
(35)2 ou (0x23)16 |
|
6 bits |
5 bits |
5 bits |
5 bits |
5 bits |
6 bits |
Exemplo:
|
opcode |
rs |
rt |
rd |
shamt |
funct |
|
0 |
$s1 |
$s2 |
$s0 |
0 |
35 |
|
0 |
17 |
18 |
16 |
0 |
35 |
|
000000 |
10001 |
10010 |
10000 |
00000 |
100011 |
No Mars ficará da seguinte forma:
.text li $s1, -10000 li $s2, +15000 SUBU $s0, $s1, $s2
Conclusão
Como vocês puderam ver, as instruções se comportam praticamente da mesma forma. Tendo como base estes exemplos, vocês já serão capazes de entender o funcionamento das outras. Como sugestão para aprofundar seus estudos, acesse o site do MIPS Technologies, baixe todo o material correspondente a MIPS32bits e dê uma olhada na descrição das instruções. A propósito, muito do que temos estudado nesta série tem como fonte esses documentos, inclusive este artigo! É isso pessoal, bons estudos e até o próximo artigo.
Saiba mais
Entendendo a Aritmética em Ponto Fixo










