Convertendo Código de Máquina em Assembly MIPS - Parte 1

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

Oi pessoal. No último artigo eu mostrei a vocês como começar a trabalhar com ponto flutuante. Desde então, algumas pessoas me procuraram para tirar dúvidas sobre o MIPS, e então tive algumas ideias para dar continuidade na série. Hoje, portanto, mostrarei a vocês como converter um código de máquina em Assembly Mips, que é um dos tópicos que geram bastante dúvidas. O artigo será na forma de resolução de um exercício, para ficar mais fácil o entendimento tá ok! Então, primeiro darei o enunciado e, a partir dele, farei a resolução passo a passo. Bora lá?

 

Enunciado

 

Considere que estamos trabalhando com uma máquina litte-endian. Considere também a memória de dados apresentada na Tabela I, a memória de instruções apresentada na Tabela II, ambas em hexadecimal, e o banco de registradores apresentado na Tabela III. Faça:

  1. Converta a memória de instruções em código Assembly MIPS;
  2. Quais tipos de instruções estão presentes?
  3. Quantas instruções de cada tipo estão presentes?
  4. Quantos bytes estão contidos na memória de dados?
  5. Quantos bytes ocupa o código Assembly?
  6. Execute o código assembly mips passo a passo, isto é, a partir dos valores iniciais dados na Tabela II, execute todas as instruções, anotando os valores resultantes. Anote mudanças nos valores de endereços de memória, de dados e do banco de registradores.

 

Tabela 1: Memória de Dados

Endereço de Memória

Dados

Byte 3

Byte 2

Byte 1

Byte 0

0x 1000 0018

12

34

56

A1

0x 1000 0014

10

05

06

07

0x 1000 0010

BB

AA

CC

11

0x 1000 000C

00

00

00

06

0x 1000 0008

A0

0B

1C

D1

0x 1000 0004

04

FF

F2

F0

0x 1000 0000

FF

AA

D1

20

 

Tabela 2: Memória de Instruções

Endereço de Memória

Instruções

Byte 3

Byte 2

Byte 1

Byte 0

0x 0040 0020

AE

13

00

10

0x 0040 001C

A2

12

00

07

0x 0040 0018

AE

11

00

00

0x 0040 0014

22

32

FF

FC

0x 0040 0010

02

2A

90

22

0x 0040 000C

01

09

88

20

0x 0040 0008

82

0A

00

15

0x 0040 0004

8E

09

00

0C

0x 0040 0000

8E

08

00

04

 

Tabela 3: Banco de Registradores

N.º do Registrador

Nome do Registrador

Conteúdo

Byte 3

Byte 2

Byte 1

Byte 0

0

$zero

 

 

 

 

1

$at

 

 

 

 

2

$v0

 

 

 

 

3

$v1

 

 

 

 

4

$a0

 

 

 

 

5

$a1

 

 

 

 

6

$a2

 

 

 

 

7

$a3

 

 

 

 

8

$t0

09

08

03

02

9

$t1

11

FF

FF

F1

10

$t2

00

00

00

0F

11

$t3

01

21

51

A1

12

$t4

00

01

10

17

13

$t5

 

 

 

 

14

$t6

 

 

 

 

15

$t7

 

 

 

 

16

$s0

10

00

00

00

17

$s1

11

22

30

03

18

$s2

A1

FF

10

C2

19

$s3

10

09

34

55

20

$s4

22

00

11

01

21

$s5

 

 

 

 

22

$s6

 

 

 

 

23

$s7

 

 

 

 

24

$t8

 

 

 

 

25

$t9

 

 

 

 

26

$k0

 

 

 

 

27

$k1

 

 

 

 

28

$gp

 

 

 

 

29

$fp

 

 

 

 

30

$sp

 

 

 

 

31

$ra

 

 

 

 

 

Resolução

 

- Questão 1: Converta a memória de instruções em código Assembly MIPS

 

Passo 1: Conversão Hexadecimal para Decimal

  • Converter os valores hexadecimais para binário, começando a partir do endereço 0x 0040 0000, isto é, a conversão começa de baixo para cima.

 

Conversão Hexadecimal para Decimal
Figura 1: Conversão Hexadecimal para Binário.

 

Passo 2: OPCODE

  • Descobrir o OPCODE de cada instrução a partir dos bits 31 a 26. Ao separar esses seis bits, consultar a referência de arquitetura do MIPS 32 bits no link 1. Um resumo você também encontra aqui no embarcados no link 2. Para facilitar, farei a separação dos bits conforme o formato de instrução R. Quando convertemos os bits em número decimal, temos o opcode correspondente da instrução. Com ele podemos consultar a referência de arquitetura e assim verificar qual é a instrução correspondente.
  1. https://www.mips.com/products/architectures/mips32-2/
  2. https://www.embarcados.com.br/primeira-instrucao-mips/

 

Formatos de Instrução
Figura 2: Separando os bits por "campos"
OPCODE
Figura 3: OPCODE

 

Passo 3: FUNCT

  • Observe que as instruções aritméticas têm opcode zero, então precisamos descobrir, qual é de fato, a operação aritmética que será executada ali. O campo FUNCT é o responsável por nos dar essa informação, e ele corresponde aos bits de 5 a 0, assim, vamos olhar para esses bits, verificar qual é o número decimal e consultar a instrução correspondente.
FUNCT
Figura 4: FUNCT

 

Passo 4: Formato de Instrução

  • Agora que já sabemos os OPCODES e os FUNCT, podemos separar os restantes dos bits, conforme o tipo de instrução identificada: tipo R, tipo I ou tipo J. Depois disso, vamos converter número binário para decimal.
Figura 5: Separando os bits

 

Passo 5: Convertendo para decimal

  • Depois de dividirmos os formatos, agora convertemos o número binário para decimal.
Figura 6: Convertendo os números binários para decimais

 

Passo 6: construindo as instruções

  • Neste passo, vamos construir corretamente as instruções, de acordo com o passo anterior. Devemos lembrar que precisamos trocar as posições dos registradores. Até o momento, usei o formato para poder identificar os valores hexadecimais, binários e decimais corretamente, mas não significa que eles estejam no campo correto.
Figura 7: Identificando as instruções

 

  • Isso nos dá as seguintes instruções:

 

Figura 8: Instruções com os nomes dos registradores

 

  • Pronto, terminamos a conversão do código de máquina para assembly. O código assembly MIPS final é:
Figura 9: Código assembly final

 

- Questão 2: Quais tipos de instruções estão presentes?

  • R.: Instruções do tipo R e tipo I

 

- Questão 3: Quantas instruções de cada tipo estão presentes?

  • R.: No total são sete instruções do tipo I e duas instruções do tipo R. São três instruções do tipo load, três instruções do tipo store, duas instruções aritméticas e uma instrução aritmética com imediato.

 

- Questão 4: Quantos bytes estão contidos na memória de dados?

  • R.: Para encontramos este valor, temos de pensar da seguinte maneira. Cada linha da memória de dados possui 32 bits, pois como bem sabemos, no MIPS 32 bits, sempre manipulamos 32 bits. A memória de dados tem 7 linhas, então, azemos 32 vezes 7, o que nos dá 224 bits. No entanto, a questão pede a quantidade de bytes. Bem, 1 byte é o mesmo que 8 bits, então, dividimos 224 bits por 8 e temos como resultado 28 bytes. De maneira forma, a conta seria o seguinte:

 

TotalBytes = (totalLinhas x 32) / 8

 

- Questão 5: Quantos bytes ocupa o código Assembly?

  • R.: Aqui usamos o mesmo racicínio da questão anterior. Assim temos que a memória de instruções possui 9 linhas, portanto: 9 * 32 = 288 bits, e 288/8 = 36 bytes

 

Conclusão deste artigo

 

Até aqui mostrei como se converte um código de máquina em código Asssembly. Mostratei a resolução da questão número 6 no próximo artigo, para que este não fique muito longo. Tudo bem galera? Tendo dúvidas, por favor, deixem aqui nos comentários.

Outros artigos da série

<< Ponto Flutuante no MIPSMIPS: Resolução dos exercícios - Parte 1 >>
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