( 0,5 pontos) Por que o MIPS não tem uma instrução que subtraia imediato?
Passo 1
O enunciado pergunta por que o conjunto de instruções MIPS não inclui uma instrução específica para “subtrair imediato” (ou seja, uma instrução do tipo subi que faria
).
Informações relevantes que temos (implícitas na pergunta e úteis para resolver):
Informações relevantes que temos (implícitas na pergunta e úteis para resolver):
- MIPS já tem instruções para soma imediata (
e ) e para subtração entre registradores ( e ). - O campo imediato nas instruções do tipo I em MIPS tem 16 bits e é interpretado com sinal (sign-extended) quando usado por
. - Em arquiteturas que usam complemento de dois, subtração pode ser realizada como adição do negativo.
Passo 2
Conceito chave: subtração como adição do complemento de dois.
Expliquei isso porque é o fundamento que justifica a ausência de uma instrução “subi”. A identidade aritmética é:
Expliquei isso porque é o fundamento que justifica a ausência de uma instrução “subi”. A identidade aritmética é:
Em sistemas que usam representação em complemento de dois, representar
é natural — basta inverter os bits de
e somar 1, ou, visto do ponto de vista da ALU, tratar
como um valor inteiro comum e usar a mesma unidade de soma. Portanto, do ponto de vista lógico e físico, subtrair é a mesma operação da adição, apenas com o segundo operando negado.
Passo 3
Como isso se aplica ao MIPS na prática: usar
com imediato negativo.
- A instrução
faz , onde é um imediato de 16 bits com sinal (é sign-extended para 32 bits antes da soma). - Se você quer fazer
, basta escrever:
addi $t, $s, -7
(ou seja, usarcomo imediato).
Isto realiza exatamente a subtração imediata, porque. Portanto, a funcionalidade que uma hipotética instrução daria já está disponível com .
Passo 4
Por que não colocar uma instrução separada então? — motivação de projeto do ISA (RISC) e economia de recursos:
- Economia de espaço de codificação: campos de opcode são limitados (por exemplo, 6 bits em MIPS clássico). Incluir instruções redundantes desperdiça esse espaço que pode ser usado para instruções realmente novas.
- Simplicidade e regularidade: arquiteturas RISC (como MIPS) preferem poucas instruções “orthogonais” e simples. Ter várias instruções que fazem a mesma coisa com pequena variação aumenta complexidade do decodificador e do manual, sem ganho real de funcionalidade.
- Implementação física: a ALU já realiza adição; para subtração a mesma ALU pode receber o operando negado. Não há ganho hardware significativo em ter um novo opcode que só difere pelo sinal do imediato.
- Manutenção do conjunto mínimo e previsível de instruções facilita otimizações, pipeline e verificação formal.
Passo 5
Comportamento de overflow e instruções relacionadas (
vs
):
-
detecta overflow aritmético e gera exceção em caso de estouro em aritmética com sinal. Se você usá-la com imediato negativo para fazer subtração, o tratamento de overflow é o mesmo que a hipotética teria. -
não gera exceção de overflow (a operação é realizada modulo ). Se você quer evitar exceção, pode usar com imediato negativo.
Isso mostra que, além de redundância funcional, já existem variantes que cobrem comportamento com/sem exceção.
Passo 6
Assembler e pseudo-instruções: como usuários acabam tendo uma instrução “subi” sem que o hardware a suporte.
- Muitos montadores aceitam pseudo-instruções como
e simplesmente as traduzem para (ou para uma sequência de instruções se o imediato não couber em 16 bits). - Se o imediato não cabe em 16 bits (por exemplo, você quer subtrair
), o montador gera uma sequência: carrega o imediato em um registrador com / ou usa (pseudo-instrução) e então usa entre registradores. Assim, a sintaxe amigável não exige instrução nova no hardware.
Passo 7
Um exemplo numérico simples para fixar:
Queremos . Em MIPS escrevemos:
addi $a, $b, -3
No nível aritmético, isso executa
Queremos
addi $a, $b, -3
No nível aritmético, isso executa
usando o imediato de 16 bits com sign-extension. Se fosse
(imediato maior que 16 bits), o montador gera código para carregar
num registrador e faz uma subtração registrador-registrador.
Passo 8
Resumo didático e motivacional (curto e direto): a instrução de subtrair imediato seria redundante porque a adição com imediato negativo faz o mesmo trabalho; por razões de economia de codificação, simplicidade do ISA e da implementação, o MIPS prefere não duplicar instruções e deixa o montador fornecer uma pseudo-instrução se for conveniente. Você já sabe fazer isso na prova: basta lembrar que subtração = adição do negativo e que o imediato em MIPS é sign-extended de 16 bits.
Resposta
Porque é desnecessária: a subtração com imediato é realizada usando
com imediato negativo (ou
quando não se quer exceção de overflow), poupando espaço de opcode e mantendo o ISA simples; montadores fornecem uma pseudo-instrução
que é expandida para essa sequência quando conveniente.