Oi galera! No último artigo falei com vocês a respeito do IF SIMPLES, usando uma instrução chamada BEQ. Hoje veremos como compilar uma instrução de IF COMPOSTO em linguagem de alto nível para MIPS, usando outra instrução chamada BNE (BRANCH ON NOT EQUAL). Também introduzirei um novo formato de instrução a partir de uma instrução de DESVIO INCONDICIONAL chamada JUMP e abreviada com J. É necessário que você siga a ordem de postagem da série ok? Caso não tenha lido o artigo IF SIMPLES, por favor, leia-o antes deste, fechado? Vamos lá!
Relembrando
Até agora, em nosso estudo sobre MIPS 32 bits, vimos as seguintes instruções:
Tabela 1: Conjunto de Instruções MIPS
| Categoria | Instrução | Exemplo | Significado | |
| Aritmética | Adição | add $s0, $s1, $s2 | $s0 = $s1 + $s2 | |
| Subtração | sub $s0, $s1, $s2 | $s0 = $s1 – $s2 | ||
| Transferência de Dados | Load Word | lw $s0, 10 ( $s1) | $s0 = Memória[$s1+10] | Carregar Palavra |
| Store Word | sw $s0, 10 ( $s1) | Memória[$s1+10] = $s1 | Armazenar Palavra | |
| Desvio Condicional | Branch on Equal | beq $s0, $s1, L1 | if($s0 == $s1) go to L1 | Desvie se igual. Teste de igualdade. |
| Branch on not Equal | bne $s0, $s1, L1 | if($s0 != $s1) go to L1 | Desvie se não for igual. Teste de desigualdade | |
| Desvio Incondicional | Jump | j 2500 | go to 2500 | Desvia para o endereço de destino |
As instruções BNE e J serão estudadas hoje, portanto já as inclui na tabela para facilitar! Observando a Tabela notamos que não há muita diferença entre BNE e BEQ: ambas são instruções de desvio condicional, entretanto uma testa a igualdade e a outra testa a desigualdade.
A instrução BNE
“Uma instrução de desvio é uma instrução que requer a comparação de dois valores e que leva em conta uma transferência de controle subsequente para um novo endereço no programa, com base no resultado da comparação.” (Patterson e Hanessey, 2014).
A instrução BNE avalia os valores armazenados em dois registradores diferentes. Se o valor no registrador 1 não for igual ao valor no registrador 2, então um desvio ocorre para um endereço, às vezes identificado por um Label. O formato da instrução é apresentado abaixo:
| OpCode | Registrador1 | Registrador2 | Desvio |
| 6 bits | 5 bits | 5 bits | 16 bits |
A sintaxe da instrução é: BNE registrador1, registrador2, desvio
A função da instrução BNE é: a próxima instrução a ser executada é aquela que estiver armazenada no endereço do LABEL se o valor no registrador1 for diferente do valor no registrador2, caso contrário, a execução do programa MIPS continua na sequência.
A Figura 1 apresenta o fluxograma das instruções BNE e BEQ. A instrução BEQ é codificada com o número decimal 04, enquanto BNE é 05.
O formato da instrução J é um tipo diferente das instruções R e I. As instruções J têm apenas dois campos, sendo o OPCODE com 6 bits e o Endereço com 26 bits. A instrução J é codificada com o número decimal 02.
| OpCode | Endereço |
| 6 bits | 26 bits |
IF Composto
Dado o código em linguagem de alto nível (Linguagem C) abaixo, faça:
- Linguagem de Montagem
- Linguagem de Máquina
- Representação de Linguagem de Máquina
- Código de Máquina
Considere f = $s0; g = $s1; h = $s2; i = $s3 e j = $s4
if( i == j )
f = g + h; //resposta verdadeira
else
f = g – h; //resposta falsa
a. Linguagem de Montagem
Vamos começar com if ( i == j ). Como agora temos um IF Composto, então, o endereço para o qual desviaremos será o ELSE! Sim, o ELSE agora é o nosso Label. Assim:
BNE $s3, $s4, Else # desvia para ELSE se i < > j
Isso parece confuso pra você? Usamos BNE em uma instrução originalmente de igualdade, i == j, mas BNE testa uma desigualdade. Bem, de acordo com os criadores do MIPS, o código será mais eficiente se for testada a desigualdade, isto é, se testarmos o THEN primeiro. Não deu pra entender? Vou tentar elucidar pra vocês, mas caso ainda persistam dúvidas, me avisem nos comentários deste artigo. Primeiro, vamos fazer o teste para o IF em C, supondo i = 10 e j = 5. Veja a Figura 2:
Assim, if ( i == j ) temos if ( 10 == 5 ). 10 é igual a 5? Não! Então, vá para ELSE, isto é, execute f = g – h. Como veremos no tópico de PIPELINE, muitas arquiteturas de conjuntos de instruções, incluindo o MIPS, consideram que o desvio sempre ocorre.
Ambas as instruções BEQ e BNE FORÇAM a ida para o bloco de comando ELSE, sempre devemos nos lembrar disso. BEQ força a entrada para ELSE quando o conteúdo do primeiro registrador É IGUAL ao segundo registrador. BNE força a entrada para ELSE quando o conteúdo do primeiro registrador É DIFERENTE do conteúdo do segundo registrador. Em nosso exemplo, estamos fazendo if(i==j), então, se i for igual a j, ele vai entrar no bloco THEN, se i for diferente de j ele vai para ELSE.
Se usarmos BEQ funcionará? Bom, BEQ forçará a entrada para ELSE se e somente se i for igual a j. Quando no código em alto nível vai entrar no ELSE? Entrará no ELSE quando i for diferente de j e não o contrário. É por isso que usamos BNE ao invés de BEQ, pois queremos tratar o desvio condicional primeiro. A segunda linha do código em C é a adição, essa é fácil de compilar né?
ADD $s0, $s1, $s2 # f = g + h (salta esta instrução se i <> j)
Agora, precisamos adicionar uma instrução MIPS que chama-se JUMP e é abreviada como J. Temos de adicionar essa instrução para indicar o fim da execução desse bloco de instruções e, também, para que o processador continue a executar o programa. Essa instrução é um desvio INCONDICIONAL e EXIT indica o fim desse bloco de programa.
J Exit # desvia para exit
Continuando a compilação para MIPS, a próxima linha em C é o ELSE e dentro dele temos a instrução de subtração. Ficará assim:
ELSE sub $s0, $s1, $s2 # f = g – h (salta esta instrução se i = j)
EXIT:
Dessa forma, a Linguagem de Montagem final é:
BNE $s3, $s4, Else # desvia para ELSE se i < > j
ADD $s0, $s1, $s2 # f = g + h (salta esta instrução se i <> j)
J Exit # desvia para exit
Else: SUB $s0, $s1, $s2 # f = g – h (salta esta instrução se i = j
Exit:
b. Linguagem de Máquina
Como sabemos, a linguagem de máquina é apenas a substituição dos nomes dos registradores pelo seu respectivo número.
BNE $19, $20, Else # desvia para ELSE se i < > j
ADD $16, $17, $18 # f = g + h (salta esta instrução se i <> j)
J Exit # desvia para exit
Else: SUB $16, $17, $18 # f = g – h (salta esta instrução se i = j
Exit:
c. Representação da Linguagem de Máquina
Como sabemos, a representação da linguagem de máquina é apenas a “conversão” das instruções de Linguagem de Máquina para os seus respectivos formatos.
| Endereço | OpCode | rs | rt | rd | shamt | funct |
| 10 000 | 4 | 19 | 20 | 10 016 | ||
| 10 004 | 0 | 17 | 18 | 16 | 0 | 32 |
| 10 008 | 2 | 10 020 | ||||
| 10 016 | 0 | 17 | 18 | 16 | 0 | 34 |
| 10 020 | EXIT |
d. Código de Máquina
Como sabemos, o código de máquina é a “conversão” representação da Linguagem de Máquina para o código de máquina.
| Endereço | OpCode | rs | rt | rd | shamt | funct |
| 10 000 | 4 | 19 | 20 | 10 016 | ||
| 10 004 | 0 | 17 | 18 | 16 | 0 | 32 |
| 10 008 | 2 | 10 020 | ||||
| 10 016 | 0 | 17 | 18 | 16 | 0 | 34 |
| 10 020 | EXIT |
| Endereço | OpCode | rs | rt | rd | shamt | funct |
| 10 000 | 000 100 | 10011 | 10100 | 0010 0111 0010 0000 | ||
| 10 004 | 000 000 | 10001 | 10010 | 10000 | 00000 | 100 000 |
| 10 008 | 000 010 | 00 0000 0000 0010 0111 0010 0100 | ||||
| 10 016 | 000 000 | 10001 | 10010 | 10000 | 00000 | 100 010 |
| 10 020 | EXIT |
Assim:
00010010011101000010011100100000
00000010001100101000000000100000
00001000000000000010011100100100
00000010001100101000000000100010
Exercícios
Tente resolver os exercícios abaixo. Se houver dúvidas, deixe nos comentários. Os dois últimos exercícios vocês poderão fazê-lo depois de ler o artigo sobre a instrução SLT tudo bem?!
if ( a == b ) c = a + b; a = b - c; else b = a + c; c = b - c;
if ( a != b ) c = a - b; a = b + c; else b = a - c; c = b + c;
if ( a > b ) c = a - b; a = b + c; else b = a - c; c = b + c;
if ( a < b ) c = a + b; a = b - c; else b = a + c; c = b - c;
Referências
PATTERSON, D. A.; Hennessy, J. L. Organização e Projeto de Computadores: A Interface Hardware/Software. 4.ª ed. Rio de Janeiro: Elsevier, 2014. Capítulo 2 (páginas de 58 à 179)





Oi Eliane, muito obrigada pela sua ajuda. Eu estava procurando por vídeo aulas e não achei nenhuma interessante, vi essa matéria e confesso que fiquei com um pouco de preguiça e receio de não entender. Mas é tudo muito simples e explicativo. Obrigada ❤️????????
Que bom fico feliz! Tenho alguns vídeos no meu canal do youtube, se quiser de uma olhada la ta bom. [ ]s
Oi Elaine!
Queria agradecer pelo material, está muito bom e didático, consegui entender com a sua explicação algumas coisas que ainda não estavam muito claras pra mim e que eu não tinha entendido com outros professores. Ta me salvando na disciplina! Muito obrigada! 🙂
Opa! Que bom, fico feliz =)
bne $19, $20, Else # desvia para ELSE se i j add $16, $17, $18 # f = g + h (salta esta instrução se i j) j Exit # desvia para exit Else: sub $16, $17, $18 # f = g – h (salta esta instrução se i = j Exit Como sabemos, a representação da linguagem de máquina é apenas a “conversão” das instruções de Linguagem de Máquina para os seus respectivos formatos. Endereço OpCode rs rt rd shamt funct 10 000 4 19 20 10 016 10 004 0 17 18 16 0 32 10 008 2… Leia mais »
Oi Tatiana! Você não entendeu o shmat? Onde tem essa palavra? Seria shamt? Se for o shamt, eu falo sobre ele em outros artigos. Shamt é um campo utilizado apenas para instruções de deslocamento, nas outras operações ele deve constar como zero.
Boa noite. Muito bom o seu material, agradeço por compartilhar. Sou estudando de graduação de CC. Fiquei com dúvida quanto as condições a > b ou a < b.
Oi Carlos! Qual exatamente é a dúvida? Não está muito claro pra mim o que você não entendeu. Grata