Sinal e Overflow no MIPS

instrução MIPS LW e SW IF Simples no MIPS

Oi pessoal! Dando continuidade à série MIPS, hoje mostrarei como são tratados os números com sinal, isto é, -1 é a mesma coisa que +1? Isto é importante pois algumas instruções trabalham com essa questão, portanto, vamos ver como funciona o sinal do número, positivo e negativo. Bora!

 

 

Representação de Números com e sem Sinal

 

Os números são divididos pelos positivos e negativos, e o zero. É fácil pra gente entender isso, mas o computador não sabe fazer isso sozinho, na verdade os projetistas têm de pensar em uma forma de dizer ao microprocessador como lidar com números positivos e negativos. E não nos esqueçamos que isso também se aplica a números quebrados, isto é, números reais, números de ponto flutuante, e que os nossos microprocessadores só conhecem 0 e 1.

 

Normalmente, o sinal positivo é representado com o bit 0 e o sinal negativo é representado com o bit 1. O número é então representado com a sua magnitude mais o bit de sinal, onde a magnitude é a quantidade de bits que pode representar o número. O bit de sinal fica sempre no MSB (Most Significant Bit ou Bit Mais Significativo) do número, que fica mais à esquerda. LSB é o nome dado ao bit mais à direita do número, ou seja, o Least Significant Bit (Bit Menos Significativo). O MSB varia conforme a quantidade de bits que o sistema de computação trabalha. Se for 64 bits, então o bit de sinal fica no bit63, se for 32 bits, então o bit de sinal fica no bit31, e assim por diante.

 

BIT DE SINALMAGNITUDE
0 (+) OU 1 (-)bits

 

Os sistemas de numeração mais utilizados em computação são: binário (2), octal (8), hexadecimal (16) e decimal (10). Podemos converter as bases dos números, isto é, passar da base binária para a base decimal, e vice-versa, usando métodos de conversão de bases. Para elucidar, vamos ver como fica o número +11 nos três sistemas de numeração. Em binário:

 

Sinal e Overflow no MIPS - Encontrando o valor binário de +11
Figura 1: Encontrando o valor binário de +11

 

Portanto, 11 em binário é 1011, e +11 é 01001, em que 0 é o bit de sinal e 1011 é a magnitude. Bom, apenas para reforçar que esses tipos de conversões já devem ser conhecidas por vocês, estou apenas recapitulando aqui, para que todos possam acompanhar o meu raciocínio e a minha explicação sobre a questão do SINAL. Quando convertemos números decimais para binário, nós usamos a base binária para tal, ou seja, 2x, onde cada posição tem um valor na base 2 correspondente, começando sempre da direita para esquerda, conforme mostra a Figura 1.

 

Para converter para as bases Octal e Hexadecimal, também usaremos a base binária, porém, dividiremos o Octal em grupos de 3 bits, e o Hexadecimal em grupos de 4 bits. Portanto, a cada 3 bits da base binária, teremos 1 bit na base Octal e, a cada 4 bits da base binária, teremos 1 bit na base Hexadecimal, também seguindo a ordem da direita para a esquerda. Não nos esqueçamos que para obter o valor correspondente, precisamos somar as posições que contém o valor 1.

 

Figura 2: Convertendo 11 para Octal
Figura 3: Convertendo 11 para Hexadecimal

 

Ótimo, fazendo isso com o número positivo é fácil e simples, aparentemente, mas e com o número negativo? Até é fácil de fazer isso na mão, mas em termos de projeto de microprocessadores não é tão simples assim e isso gerou inúmeros problemas. Assim, a representação por Sinal e Magnitude não é utilizada na prática, ao invés, é utilizado algo diferente, mais funcional e simples até, que chamamos de complemento a 2. Para facilitar, vocês podem seguir os passos a seguir ao utilizar esta técnica:

  • Passo 1: Converter o número decimal, ou octal, ou hexadecimal para número binário;
  • Passo 2: Encontrar o complemento a 1 do número binário;
  • Passo 3: Encontrar o complemento a 2 do número binário;
  • Passo 4: Tirar a prova realizando o mesmo procedimento para o número positivo/negativo;
  • Passo 5: Converter para a base desejada.

 

Complemento a 1

 

Para encontrar o complemento a 1 de um número, você precisa inverter o número, isto é, onde é zero troque por um e onde é um troque por zero. Exemplo:

 

+11001011
Complemento a 1 [C1] de +11110100

 

Complemento a 2

 

Para encontrar o complemento a 2 você deverá somar 1 ao C1, onde esse 1 deve estar no bit0, da seguinte forma:

 

Encontrando o valor do complemento a 2 de +11
Figura 4: Encontrando o valor do complemento a 2 de +11

 

Assim, o complemento a 2 [C2] de +11 é 110101, ou seja, este é o valor binário de -11. Bem, se você notar o número + 11 começa com zero e o número +11 em C2 começa com um, coincidência será? De qualquer forma, números negativos sempre têm o MSB com 1, e números positivos sempre têm o MSB com 0, da mesma forma que números pares sempre têm o bit0 com zero e, números ímpares têm o bit0 com 1. Para tirar a prova, você fará o seguinte:

 

Encontrando o valor do complemento a 2 de -11
Figura 5: Encontrando o valor do complemento a 2 de -11

 

O resultado do complemento a 2 de -11 é exatamente +11, portanto:

 

+11001011
-11110101

 

Fácil? Difícil? O que você pode fazer para entender melhor isto são exercícios. Tente converter o máximo de números possível, assim o processo ficará mais simples. De qualquer forma, o BIT DE SINAL continua existindo aqui neste método, vamos entender. Um número como o +11, quando o convertemos tem apenas 5 bits, isto é, ele pode ser representado com apenas 5 bits, mas uma máquina que trabalhe com 32 bits precisa de todos os 32 bits preenchidos para a manipulação do número. Assim, um número com o +11 ficaria assim:

 

0000 0000 0000 0000 0000 0000 0000 1011

 

e o -11 ficaria assim:

 

1111 1111 1111 1111 1111 1111 1111 0101

 

Onde o bit roxo é o bit de sinal quando o número é formado por 5 bits. O bit marcado em azul é o MSB, os bits em verde são o número propriamente dito, o resto disso tudo é a extensão do sinal, isto é, números 1s e 0s foram copiados do sinal (que está em roxo) para completar os 32 bits. O microprocessador agora consegue saber que esse número é positivo ou negativo analisando apenas o BIT DE SINAL, que será o bit31, sendo 0 = positivo e 1 = negativo. Em uma máquina 32 bits a representação dos números inteiros é dada de -231 até (231-1).

 

 

Casos Especiais

 

Tem uma situação interessante quando usamos complemento a 2. Os números binários que ficam nas extremidades da magnitude, entre as faixas positivas e negativas, são um caso particular, pois nestes casos, o complemento de 2 destes números é o próprio número. Vou elucidar mostrando o complemento a 2 do numero 8.

 

Encontrando o complemento a 2 de +8
Figura 6: Encontrando o complemento a 2 de +8

 

Encontrando o complemento a 2 de -8
Figura 7: Encontrando o complemento a 2 de -8

 

Para quem não entendeu a parte de aritmética, ou seja, porque 1 + 1 = 10, aconselho a estudar ARITMÉTICA DIGITAL, que é referente ao projeto, estudo e aprendizado de operações matemáticas aplicadas a bits. Continuando, perceberam que o número 8 é exatamente o mesmo? A única coisa que mudou foi o sinal, 1 para negativo e 0 para positivo. Esse tipo de situação também acontece com o 16, 32, 64, 128, e assim por diante, faça o teste você mesmo. Portanto:

 

-81 1000
+80 1000

 

 

Overflow

 

O overflow ocorre quando o hardware não é capaz de representar os números que normalmente são resultados de alguma operação aritmética. Vou mostrar um exemplo bem simples do que significa o overflow e assim elucidar a problemática envolvendo essa situação em números com sinal.

 

Exemplo de Overflow
Figura 8: Exemplo de Overflow

 

Neste exemplo estou somando +9 com -4 e Carry significa "Vai um". A estratégia usada aqui foi a de descartar o bit que ficou sobrando mais à esquerda, logo após o bit de sinal. Se esse bit extra for considerado, ele poderá alterar drasticamente todos os valores, pois não corresponde à realidade. Neste exemplo o bit de sinal é zero e o bit de overflow é um, portanto, a extensão do sinal do número deve ser zero e não um. Se esse bit um for utilizado, o número deixará de ser positivo e se tornará negativo, olha só a dor de cabeça! Portanto, é preciso ter muito cuidado com o sinal do número e o overflow! Tendo em vista essas duas situações para o número binário, Sinal e Overflow, MIPS projetou diversas instruções que tratam de ambas.

 

 

Instruções com Sinal e Overflow

 

Algumas instruções MIPS trabalham com números que tenham ou não sinal, e também com o Overflow, é o caso das instruções listadas abaixo. Como são muitas instruções, nós não estudaremos todas, porém, a partir do exemplo de algumas, já será possível compreender o comportamento das outras.

  • MULTU = Multiplicação sem sinal;
  • MULOU = Multiplicação sem sinal com overflow;
  • MADDU = Multiplicação Adição sem sinal;
  • MSUB = Multiplicação Subtração sem sinal;
  • REMU = Resto sem sinal;
  • SLTU = Set se menor que sem sinal;
  • SLTIU = Set se menor que imediato sem sinal;
  • SGEU = Set se menor ou igual sem sinal;
  • SGTU = Set se maior que sem sinal;
  • SLEU = Set se menor ou igual sem sinal;
  • BGEU = Branch se for maior ou igual com sinal;
  • BGTU = Branch se for maior sem sinal;
  • BLEU = Branch se for menor ou igual sem sinal;
  • BLTU = Branch se for menor sem sinal;
  • LBU = Load Byte sem sinal;
  • LHU = Load Halfword sem sinal.

 

Até o presente artigo, praticamente todas as instruções que estudamos não tratam do Overflow e Sinal de forma explícita. Por exemplo, as instruções de adição com overflow e sem overflow têm basicamente os mesmos formatos e características, o que muda são os opcodes e mnemônicos: ADD (20) e ADDU (21). A instrução "set se menor que" é o mesmo caso, SLT (42) e SLTU (43). Finalizando, quando precisar trabalhar de forma explícita com sinal e overflow, utilize as instruções projetadas para essas situações.

 

 

Conclusão

 

Bem, basicamente é desta forma que a máquina entende os números com sinal. Agora que você já sabe como isso é feito, podemos trabalhar com instruções específicas para números com sinal. Além disso, as Linguagens de Programação de Médio e Alto Nível também podem fornecer recursos para diferenciar números com e sem sinal, como, por exemplo, a Linguagem C, que permite o uso de UNSIGNED e SIGNED para determinar se aquele tipo numérico tem sinal ou não. Preparados? Estudem, deixem suas dúvidas aqui, responderei assim que puder e, no próximo artigo, mais novidades. Até pessoal.

 

 

Saiba mais

 

Entendendo a Aritmética em Ponto Fixo

Utilizando o ULP do ESP32 para co-processamento

Tipos de dados para uso em algoritmos

Outros artigos da série

<< Executando um Array no MARS para MIPSCompilando instruções com ou sem Sinal, Overflow e Imediato no MIPS >>
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Elaine Cecília Gatto
Bacharel em Engenharia de Computação. Mestre em Ciência da Computação. Doutoranda em Ciência da Computação. Co-fundarora e Líder das #GarotasCPBr. Pesquisadora Convidada no Grupo de Pesquisa: "Artes em Tecnologias Emergentes" do Programa de Pós Graduação em Design na UNESP Campus Bauru. Cantora, Docente no Magistério Superior, Geek, Nerd, Otaku e Gamer. Apaixonada por Michael Jackson, Macross, Rocky Balboa, Séries, Filmes, Cervejas e Vinhos. Mais informações sobre mim você encontra em: http://lattes.cnpq.br/8559022477811603.

Deixe um comentário

avatar
 
  Notificações  
Notificar