MIPS: Instruções de Divisão

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

Oi pessoal! No artigo anterior eu expliquei para vocês as instruções de Multiplicação do conjunto de instruções MIPS 32 bits. Hoje vou mostrar como funcionam as instruções de Divisão. Lembrem-se: todas as informações referentes à Arquitetura MIPS estão disponíveis no site oficial neste link: https://www.mips.com.

 

Divisão

 

Divisão com Overflow

 

Div: Divide Word – Divide uma palavra. Esta instrução divide inteiros com sinal de 32 bits. De acordo coma documentação, nenhuma exceção aritmética ocorre sob quaisquer circunstâncias. Se as condições de divisão por zero ou de overflow forem detectadas e alguma ação for tomada, a instrução de divisão ocorrerá normalmente seguida por instruções adicionais para verificar um divisor zero e/ou overflow.

 

Se a divisão for assíncrona, a verificação do divisor zero poderá ser executada paralelamente à divisão. A ação tomada em qualquer divisão por zero ou estouro é uma convenção dentro do próprio programa ou, mais tipicamente, dentro do software do sistema. Uma possibilidade é obter uma exceção BREAK com um valor de campo de código para sinalizar o problema para o software do sistema.

 

Portanto, por padrão, a maioria dos compiladores da arquitetura MIPS emitirá instruções adicionais para verificar os casos de divisão por zero e overflow quando esta instrução for usada. Em muitos compiladores, o mnemônico “DIV r0, rs, rt” do Assembler pode ser usado para evitar que essas instruções de teste adicionais sejam emitidas.

 

Sintaxe: div rs, rt

 

Formato:     

op

rs

rt

rd

shamt

funct

0

 

 

0

0x1a

6 bits

5 bits

5 bits

10 bits

6 bits

 

 

Exemplo:

Vamos dividir 10 por 2. O resultado da divisão de 10 por 2 é 5. Nesta instrução, o resto é armazenado no registrador HI e o quociente no registrador LO, conforme você verá na execução no MARS.

.text
         li $s2, 10   #carrega o valor imediato 10 no registrador s2 (li = load immediate)
         li $s3, 2    #carrega o valor imediato 3 no registrador s3
         div $s2, $s3 #executa a divisão entre s2 e s3

 

Mas e se fizermos uma divisão que o resultado dê um número fracionário? Vamos dividir 10 por 3 e ver o que acontece:

.text
    li $s2, 10   #carrega o valor imediato 10 no registrador s2 (li = load immediate)
    li $s3, 3    #carrega o valor imediato 3 no registrador s3
    div $s2, $s3 #executa a divisão entre s2 e s3

 

O resultado dessa divisão é 3.333333. Se você observar bem, nesta instrução, o MARS mostra apenas a parte inteira do resultado, a parte fracionária é ignorada. Isto acontece, pois, esta instrução é utilizada para divisão entre números inteiros, e não números de ponto flutuante. Em artigos futuros estudaremos as instruções de ponto flutuante.

 

Divisão sem Overflow

 

Divu: Divide Unsigned Word – Divide uma palavra sem sinal. Esta instrução divide um inteiro sem sinal de 32 bits. O valor do registrador rs é dividido pelo valor do registrador rt, ambos tem palavra de tamanho 32 bits.

 

Sintaxe: divu rs, rt

 

Formato:     

op

rs

rt

rd

shamt

funct

0

 

 

0

0x1b

6 bits

5 bits

5 bits

10 bits

6 bits

 

Exemplo:

Vamos dividir 10 por 2. O resultado da divisão de 10 por 2 é 5. Nesta instrução, o resto é armazenado no registrador HI e o quociente no registrador LO, conforme você verá na execução no MARS.

.text
    li $s2, 10    #carrega o valor imediato 10 no registrador s2 (li = load immediate)
    li $s3, 2     #carrega o valor imediato 3 no registrador s3
    divu $s2, $s3 #executa a divisão entre s2 e s3

 

Agora vamos dividir 10 por 3:

.text
    li $s2, 10    #carrega o valor imediato 10 no registrador s2 (li = load immediate)
    li $s3, 3     #carrega o valor imediato 3 no registrador s3
    divu $s2, $s3 #executa a divisão entre s2 e s3

 

Lembre-se, as instruções DIV e DIVU são para números inteiros e que o resultado de uma divisão por zero é imprevisível! Faça o teste! Tente dividir 10 por 0!

 

Pseudoinstrução de Divisão com Overflow

 

A diferença desta instrução para a instrução DIV comum, é que a DIV em pseudoinstrução utiliza três registradores, ao invés de dois, como pode ser visto na sintaxe. O registrador destino agora armazena o quociente.

 

Sintaxe: div r_destino, r_source1, r_source2

 

Exemplo:

Nesta instrução, o resto é armazenado no registrador HI, o quociente no registrador LO, e então o valor que está em LO, que é o quociente, é transferido para o registrador destino designado na instrução.

.text
    li $s2, 10        #carrega o valor imediato 10 no registrador s2 (li = load immediate)
    li $s3, 2         #carrega o valor imediato 3 no registrador s3
    div $s1, $s2, $s3 #executa a divisão entre s2 e s3

 

Observe a Figura 1. Ela apresenta uma parte da tela do simulador MARS após a execução deste trecho de código. Note que a pseudoinstrução gerou mais instruções e, também aqui, como já explicado no artigo sobre multiplicação, aparecem as instruções BNE e MFLO. Se você ainda não leu o artigo sobre multiplicação, aproveite agora para fazer isto e entender o que está acontecendo no MARS.

 

 

 

Pseudoinstrução de Divisão sem Overflow

 

A diferença desta instrução para a instrução DIVU comum, é que a DIVU em pseudoinstrução utiliza três registradores, ao invés de dois, como pode ser visto na sintaxe. O registrador destino agora armazena o quociente.

 

Sintaxe: div r_destino, r_source1, r_source2

 

Exemplo:

Nesta instrução, o resto é armazenado no registrador HI, o quociente no registrador LO, e então o valor que está em LO, que é o quociente, é transferido para o registrador destino designado na instrução.

.text
    li $s2, 10         #carrega o valor imediato 10 no registrador s2 (li = load immediate)
    li $s3, 2          #carrega o valor imediato 3 no registrador s3
    divu $s1, $s2, $s3 #executa a divisão entre s2 e s3

 

A Figura 2 apresenta o MARS após a execução desta instrução. Note que o comportamento é praticamente idêntico ao da pseudoinstrução DIV.

 

 

Mapa de OpCode do MIPS

 

Para facilitar o seu acompanhamento nestes artigos em que falarei mais sobre o conjunto de instruções do MIPS, é bom ter sempre perto, e talvez até mesmo impresso, este Mapa de Código de Operações. Vai facilitar muito sua vida quando estiver trabalhando com MIPS. Vamos entender um pouco como devemos ler esse Mapa.

 

op(31:26): o campo opcode está contido nos bits de 26 a 31 de uma instrução

rs(25:21): o campo está contido nos bits 25 e 21

rt(20:16): o campo está contido nos bits 20 e 16

funct(4:0): o campo está contido nos bits 0 e 4

funct(5:0): as instruções de ponto flutuante são especificadas pelos bits de 0 a 5

(17:16): o campo está contido nos bits 16 e 17

(16:16): o campo está contido no bit 16

 

Os números 00, 01 até 3f, que estão à esquerda do nome das instruções, são os códigos do campo OpCode. Os valores na primeira coluna estão na base 10 e a segunda coluna estão na base 16. Os valores de código 0, 1, 16, 17, 18 e 19 são códigos de operação que levam a outras instruções, com outros códigos. Por exemplo, o código 00 em op(31:26) leva ao código 0 em funct(5:0) e o código 1, em funct(5:0), leva a outras duas instruções, as quais tem códigos diferentes.

 

 

As instruções que estão grifadas são aquelas que já conhecemos até o momento. Isso o ajudará a ter uma noção do que já aprendemos. Legal né? No fim das contas, Assembly não é tão difícil assim não é mesmo?

 

Por hora, estamos estudando as instruções que envolvem operandos inteiros. Em breve iniciaremos estudos sobre números de ponto flutuante. Fiquem atentos! Até o próximo artigo pessoal!

Outros artigos da série

<< MIPS: Instruções de MultiplicaçãoMIPS: Subtração e outras instruções >>
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.

6
Deixe um comentário

avatar
 
1 Comment threads
5 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Elaine Cecília GattoAlessandro Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Alessandro
Visitante
Alessandro

Parabéns pelo conjunto de artigos, muito bom mesmo.
Existe algum placa com CPU MIPS fácil de conseguir no mercado?