Executando um Array no MARS para MIPS

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

Oi galera! No artigo anterior ensinei vocês a testarem alguns dos códigos que fiz em um simulador bem simples, chamado MARS. No artigo de hoje darei continuidade aos testes dos exemplos, de forma que você tenha um material referencial na hora de fazer o seu próprio.

 

Exemplo 4: Array

 

Utilizarei agora o exemplo do quarto artigo desta série:

 

a = b + c[10];
LW $t0, 10 ( $s2 )
ADD $s0, $s1, $t0
LW $8, 10 ( $18 )
ADD $16, $17, $8

 

Esse exemplo será um pouco mais trabalhoso do que os outros pois estou falando de um array, de obter o valor de uma posição específica desse array, e depois somar esses valores. Não esqueça de que é preciso fazer o cálculo correto do endereço também. Antes de mais nada, veja como é o código completo em C:

 

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main(){
    setlocale(LC_ALL,"Portuguese");
    int c[15] = {3, 0, 1, 2, -6, -2, 4, 10, 3, 7, 8, -9, -15, -20, -87, 0};
    int a = 0, b = 30;
    a = b + c[10];
    printf("\n o valor de a é: %d \n", a);
}

 

Bom, para o nosso teste, eu vou descartar algumas coisas, ok? Como o FOR, por exemplo, visto que ainda não passei os detalhes para vocês sobre LOOP. Porém, ter o programa de alto nível como referência, para conseguirmos entender um pouco melhor a compilação aqui no MARS, é muito útil.

 

Primeira coisa: notem que a variável b foi declarada como um tipo inteiro e a ela foi atribuído o valor 30.

 

Segunda coisa: um array do tipo inteiro chamado c foi declarado com o tamanho de 15 posições, e já inicializado com os respectivos valores.

 

Terceira: também é declarada uma variável do tipo inteiro chamada “a”, que não é inicializada.

 

Quarta: a soma é executada.

 

Quinta coisa: impressão do resultado, a qual não mostrarei neste artigo.

 

Farei algo bem semelhante no MARS para testar o exemplo do artigo 4. Vou declarar e inicializar um array no MARS, conforme demonstra a linha abaixo:

 

.data
c: .word 3, 0, 1, 2, -6, -2, 4, 10, 3, 7, 8, -9, -15, -20, -87, 0

 

A diretiva “.data” indica que as instruções a seguir contêm dados. A diretiva “.word” armazena n quantidades de 32 bits em palavras de memórias sucessivas. Assim, determino que “c” é um label (ou rótulo) que contém os valores designados da word. Essas diretivas permitem usar o segmento de dados para armazenar e manipular dados. Assim, pode-se dizer que a linha de código abaixo, em linguagem C...

 

int c[15] = {3, 0, 1, 2, -6, -2, 4, 10, 3, 7, 8, -9, -15, -20, -87, 0};

 

...pode ser traduzida como abaixo, no MIPS:

 

.data
c: .word 3, 0, 1, 2, -6, -2, 4, 10, 3, 7, 8, -9, -15, -20, -87, 0

 

Porém, há outras formas de trabalhar com Arrays na compilação para o MIPS. Por hora, para não confundir muito, deixarei assim para que você consiga testar os exercícios depois. Além de definir e inicializar o array “c”, é necessário também definir o índice e o endereço, isto é, serão atribuídos a registradores temporários o índice específico (no caso 10) e o endereço do array. Para atribuir o endereço do array a um registrador, é preciso usar uma instrução chamada la, que significa load address, em português "carga de endereço". Determinado o array, agora basta determinar b = 30, que ficará da seguinte forma:

 

li $s1, 30         # (30)10 = (1E)16, portanto $s1 = 0 x 0000 001E      

 

O valor imediato, 30, é carregado para $s1, que é o registrador de b, lembrando que li é a instrução de load immediate. Após, é preciso carregar o endereço do array em um registrador, como a seguir:

 

la $s2, c          # c está em 0 x 0000 1001

 

Suponha que o endereço do array “c” seja (1001)2 ou (4097)10. Neste momento, na hora da execução do código Assembly no MARS, vocês vão notar que o registrador $at será utilizado para ajustar o endereço, de forma que ele passa de 0x00001001 para 0x10010000. O registrador $at é reservado para o montador, para uso exclusivo dele. A instrução la carrega o endereço do array c para o registrador $s2. Agora, é preciso especificar o índice para outro registrador, no caso do nosso exemplo, é a posição 10:

 

li $t2, 10         # (10)10 = (A)16

 

Novamente uso li, para a carga do número inteiro 10, que é um imediato, para o registrador $t2. Agora que o endereço do array já está guardado em um registrador temporário, e o índice 10 também, é preciso calcular o endereço da forma correta, conforme já expliquei em artigos anteriores.

 

add $t2, $t2, $t2         # 10 + 10 = 20 => (14)16
add $t2, $t2, $t2         # 20 + 20 = 40 => (28)16
add $t1, $t2, $s2         # (28)16 + (1001)16

 

Na terceira linha o cálculo é feito como uma soma dos dois registradores:

 

$t2

1001 0000

$s2

0000 0028

$t1

1001 0028

 

Portanto, o endereço resultante armazenado em $t1 é 0x10010028. Depois de calculado o endereço, já é possível carregar o valor contido em c[10] para o registrador $t0:

 

lw $t0, 0 ( $t1 )         

 

Na posição c[10] está armazenado o valor 8, que em hexadecimal é 00000008. Reforço também que a contagem no array começa em zero e não em um! Cuidado com este pequeno grande detalhe, ok? Bom, todo esse trabalho apenas para carregar o valor correto e então usá-lo em uma soma, que você já conhece bem:

 

add $s0, $s1, $t0        # 30 + 8 = (38)10, ou então, 001E + 0008 = (26)16

 

O código completo fica conforme a seguir. Teste o mesmo no MARS e verifique os valores, endereços e estados dos registradores.

 

.data
c: .word 3, 0, 1, 2, -6, -2, 4, 10, 3, 7, 8, -9, -15, -20, -87, 0
.text
li $s1, 30               # determinando o valor para $s1
la $s2, c                # colocando o endereço do array em $s2
li $t2, 10               # colocando o índice do array em $t2
add $t2, $t2, $t2        # “2i”
add $t2, $t2, $t2        # “4i”
add $t1, $t2, $s2        # combinando os dois componentes do endereço
lw $t0, 0 ( $t1 )        # obtendo o valor da célula do array
add $s0, $s1, $t0        # executando a soma

 

Conclusão

 

Ufa! Terminou! Quanto trabalho não! Dá pra entender porque muitas pessoas preferem programar em alto ou médio nível. Mas não desista! Apesar das dificuldades, linguagens de baixo nível em geral, são um grande aprendizado, pois te desafiam a sair da zona de conforto e a pensar um pouco diferente do que está acostumado. Sem contar que, nunca sabemos quando é que vamos precisar usar algo como isto em algum projeto, portanto, nenhum conhecimento é desperdiçado. Continuem me acompanhando, tem muito mais pela frente.

Outros artigos da série

<< Testando as instruções MIPS no MARSSinal e Overflow 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.

5
Deixe um comentário

avatar
 
3 Comment threads
2 Thread replies
3 Followers
 
Most reacted comment
Hottest comment thread
4 Comment authors
Sophia AlcântaraRodrigo RodriguesElaine Cecília GattoPatricia Silva Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Sophia Alcântara
Membro
Sophia Alcântara

Boa tarde, Elaine.
Eu não entendi um detalhe abordado:
é na linha 10: lw $t0, 0 ($t1)
não entendi o porquê do uso desse zero. Poderia me tirar esta dúvida?

Rodrigo Rodrigues
Membro
Rodrigo Rodrigues

Parabéns pelo conteúdo gerado, estava meio perdido na disciplina de AOC1 na minha universidade ajudou e muito!!! Obrigado!!!

Patricia Silva
Visitante
Patricia Silva

Cecilia, fazemos parte das lideres de comunidade da CPBR e não sabia que também eras magnifica nos artigos.
Parabéns!
Este material ajudou muito. Sucesso sempre!

Patricia Silva
Comunidade Manguebyte