Í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
Olá Pessoa! Hoje vamos aprender um pouco mais sobre o conjunto de instruções MIPS. No artigo anterior, vimos uma conversão simples. Hoje vamos usar uma instrução menos simples. Vamos lá?
Conversão de uma instrução com parênteses
Considere a seguinte instrução em linguagem C:
a = b – ( c – d ) + e
Como resolveríamos isso na mão, com uma folha de almaço? Sem saber os valores reais, e considerando a ordem de prioridade de execução das operações, a resolução dessa instrução ficaria assim:
a = b – ( c – d ) + e
a = b – T1 + e
a = T3 + e
a = T4
Onde T1, T2, T3 e T4 são os valores resultantes e o negrito/itálico representa a parte da expressão matemática que está sendo resolvida naquele instante. Se você substituir b, c, d, e e com valores de números inteiros ou reais, chegará em um resultado final. O que eu fiz acima foi uma generalização de uma resolução matemática, algo abstrato e que nos permite entender o passo a passo. Bom, se é assim que fazemos na unha, como é que faremos a conversão para MIPS? Não é muito diferente.
Linguagem de Montagem
Vamos fazer a conversão, começamos pela Linguagem de Montagem, lembrando sempre de consultar as tabelas da arquitetura do conjunto de instruções MIPS 32 bits. Como é uma instrução com parênteses, devemos primeiro resolver os parênteses, assim como em qualquer outra expressão matemática.
Depois dos parênteses, devemos voltar fazendo a leitura da expressão da ESQUERDA para a DIREITA, sem alterar a ordem em que os operandos aparecem na expressão. Então, primeiro o parênteses, depois b – ( c – d ) e somente depois somamos com e. Usaremos os seguintes registradores: a = $s0, b = $s1, c = $s2, d = $s3 e e = $s4. Também precisaremos usar registradores temporários $t para poder armazenar os valores de cada parte da expressão.
Listagem 1: Código MIPS correspondente à expressão a = b – ( c – d ) + e
1 2 3 |
SUB $t1, $s2, $s3 # $t1 = ( $s2 - $s3 ) é o mesmo que $t1 = ( c - d ) SUB $t2, $s1, $t1 # $t2 = $s1 - $t1 é o mesmo que $t2 = b - ( c - d ) ADD $s0, $t2, $s4 # $s0 = $t2 + $s4 é o mesmo que $s0 = b - ( c - d ) + e |
O caractere # nos permite comentar o código MIPS. $t1 é um registrador temporário que armazenará o resultado da subtração de ( c – d ). Assim resolvemos a primeira parte da expressão correspondente à prioridade parênteses. A próxima parte da expressão matemática a ser resolvida é b – ( c – d ).
O registrador $t1 é utilizado na linha dois e, observe, ele é o último registrador a aparecer na instrução, isto porque é ele quem guarda o valor resultante de ( c – d ). O primeiro registrador é outro temporário, $t2, que armazenará o resultado de b – ( c – d ). O segundo registrador, $s1 é correspondente à variável b. Assim, a segunda linha executa a segunda parte da expressão matemática.
A última parte da expressão é a resolução dela inteira. A última parte então que falta é b – ( c – d ) + e, agora então temos de somar e ao restante que já foi calculado. Assim na terceira linha, o primeiro registrador é o $s0, que é a variável a; o segundo registrador é $t2, que armazena o resultado de b – ( c – d ); e, por fim, o terceiro registrador da instrução é $s4, correspondente à variável e.
Você notou que a resolução da expressão é cumulativa? Uma parte da expressão é resolvida e armazenada em um registrador e depois utilizada na instrução seguinte, e assim por diante, até terminar toda a expressão. Assim sendo, podemos reescrever o código MIPS da listagem 1 para economizar um registrador temporário. Ao invés de usarmos dois registradores diferentes, podemos usar apenas um, somente $t1 e descartamos $t2. “Economizar” registradores temporários é importante, assim eles ficam livres para serem usados em outras instruções que realmente precisem. Sempre que a instrução de alto nível for acumulativa, você pode também acumular valores em um registrador, mas tome cuidado ao fazer isso, para não gerar erros no resultado final.
Listagem 2: Código MIPS correspondente à expressão a = b – ( c – d ) + e
1 2 3 |
SUB $t1, $s2, $s3 # $t1 = ( $s2 - $s3 ) é o mesmo que $t1 = ( c - d ) SUB $t1, $s1, $t1 # $t1 = $s1 - $t1 é o mesmo que $t1 = b - ( c - d ) ADD $s0, $t1, $s4 # $s0 = $t1 + $s4 é o mesmo que $s0 = b - ( c - d ) + e |
Na Listagem 2 eu substitui $t2 por $t1 pois isso não influenciará o resultado final. Ao fazer ADD $t1, $s1, $t1 o valor de $t1 será sobrescrito ao final da execução da instrução, isto é, o valor original será perdido e um novo valor será armazenado ali. Primeiro os operandos fontes, $s1 e $t1, são buscados da memória, depois eles são somados e, por último, o resultado é armazenado em $t1. Se por um acaso você precisar do valor de $t1, que é o valor de c – d, para ser usado em outra instrução posterior, então você não deve trocar $t2 por $t1, você na verdade deve manter $t2 para que o valor de $t1 não seja perdido.
Linguagem de Máquina
A linguagem de máquina corresponde a trocar os nomes dos registradores pelo seu número, então nosso código ficará assim:
Listagem 3: Código MIPS correspondente à expressão a = b – ( c – d ) + e
1 2 3 |
SUB $9, $18, $19 # $t1 = ( $s2 - $s3 ) é o mesmo que $t1 = ( c - d ) SUB $9, $17, $9 # $t1 = $s1 - $t1 é o mesmo que $t1 = b - ( c - d ) ADD $16, $9, $20 # $s0 = $t1 + $s4 é o mesmo que $s0 = b - ( c - d ) + e |
Representação
A representação corresponde a pegar as nossas instruções MIPS e colocá-las no formato correspondente, conforme mostra a Tabela 1:
Tabela 1: Representação das instruções
op | rs | rt | rd | shamt | funct |
0 | 18 | 19 | 9 | 0 | 34 |
0 | 17 | 9 | 9 | 0 | 34 |
0 | 9 | 20 | 16 | 0 | 32 |
Para preencher a tabela eu consultei o artigo anterior que contém a tabela de operações e formatos de instruções do TIPO R explicadinhos. RS e RT são os operandos FONTES e RD é o operando DESTINO. Como ADD e SUB são operações matemáticas, o código de operação delas é ZERO, mas o código de FUNCT é 32 e 34 respectivamente.
Código de Máquina
O código de máquina corresponde a pegar a representação da instrução e converte-la para número binário. OP e FUNCT são seis bits e os outros campos são cinco bits. A Tabela 2 apresenta a Tabela 1 em forma de código binário:
Tabela 2: Código binário para cada campo do formato de instrução
op | rs | rt | rd | shamt | funct |
000000 | 10010 | 10011 | 01001 | 00000 | 100010 |
000000 | 10001 | 01001 | 01001 | 00000 | 100010 |
000000 | 01001 | 10100 | 10000 | 00000 | 100000 |
Assim, o código de máquina final é o seguinte:
00000010010100110100100000100010
00000010001010010100100000100010
00000001001101001000000000100000
Exercícios
Vamos exercitar um pouco? Se tiverem dúvidas, deixem nos comentários ok?! Muito Obrigada.
Considere os seguintes registradores para cada variável: a = $s0, b = $s1, c = $s2, d = $s3, e = $s4, f = $s5.
- a = b – c
- b = a + c
- d = (a + b – c)
- f = (a + b) – d
- c = a – ( b + d)
- e = ( a – ( b – c )
- e = ( a – ( b – c ) + f )
- f = e – (a – b ) + ( b – c )
qual a funct da multiplicação?
Oi José, obrigada pelo seu comentário e desculpe a demora para responder. Estou bem ocupada com o doutorado. Dê uma olhada aqui ta bom: https://www.embarcados.com.br/mips-instrucoes-de-multiplicacao/ [ ]s
Ta Faltando um ‘(‘ no Exercício 6? E parabéns pelo conteúdo, vai me ajudar a passar na matéria kkk. Serio Muito Obrigado Mesmo, Muita Qualidade.
Oi Glaucio obrigada pelo seu comentário. Eu vou conferir. Tentarei responder e esclarecer todas as dúvidas nos artigos até domingo que vem (17/01/2021), assim como postar as respostas dos exercícios. Mais uma vez obrigada e solicito que aguarde ok. [ ]s
tem gabarito ?
Oi jean, desculpa mas não tem gabarito! Vou ver se faço um post com as soluções ok. Duvidas entre em contato.
Cadê o gabarito
Olá!!!! Ainda não sobrou um tempinho para fazer este post! Peço um pouco mais de paciência ok. Mas se tentou resolver, e ficou com dúvida em alguma parte, por favor, manifeste aqui ok. Grata
No exemplo do texto não seria na segunda linha os valores 17, 9 e 9?
Luiz, muito obrigada! Esse passou despercebido por todos. Corrigindo já.
Também estou acompanhando esse artigo, que diga-se de passagem é tudo de bom.
Estou, meio que voltando no tempo e descobrindo como tudo começou. Hoje mesmo estava dando uma olhada no site CPU Galaxy e fiquei encantado com o Intel 3002 de apenas 2 bits, mas que trabalhando em conjunto com vários outros 3002 poderia ser criado um de 16 bits, sendo que alguns Intel de 8 bits poderia manusear somente 8 bits de cada vez. Muito legal isso.
Falarei sobre esses microprocessadores antigos também! Aguarde.
Oba!
aehoiuhiuahiu