Compilando Arrays com índice variável no MIPS

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

Oi pessoal! Tudo bem? Espero que sim. Hoje retomo o assunto ARRAY, isto porque mostrei a vocês como compilar expressões matemáticas para MIPS quando o ARRAY, com índice específico, é um operando e quando ele armazena o resultado de uma operação. Porém faltou mostrar a compilação de quando o ARRAY tem um índice variável e não uma “posição” específica. Vamos lá então!

 

 

Compilando

 

Vou usar como exemplo a seguinte expressão matemática:

 

g = h + a[i];

 

Também farei a seguinte atribuição de registradores:

 

g = $s0            h = $s1            a = $s2            i = $s3

 

Note que agora o Array a possui um índice variável, que neste caso é o i, e não mais um índice específico, como, por exemplo, a[3] ou a[10]. Como então definir o i? Não sabemos quem é i, isso é verdade, não sabemos o seu valor, a sua posição, porém sabemos que i tem um endereço.

 

Também sabemos que o primeiro passo para a compilação desta expressão é ler a[i] carregando-o para um registrador temporário e, para isso, precisamos do seu endereço. Conforme explicado no artigo sobre a instrução SLT, o MIPS trabalha com endereçamento em bytes e, por isso, é necessário realizar um cálculo para o endereço, o qual sempre é múltiplo de 4. Assim sendo, no caso dos índices variáveis em Arrays, devemos multiplicar esses índices por 4. Mas, como fazer isto? Existem duas formas;

 

1 - Somar i até chegar em 4i

 

Nesta forma usamos a operação de soma, ADD, para chegar em 4*i, não fazemos a multiplicação direta. O registrador $s3 é a variável i, portanto, vamos começar somando esse registrador, armazenando o resultado em um registrador temporário:

 

ADD $t1, $s3, $s3                 # $t1 = $s3 + $s3        $t1 = i + i = 2*i

 

O registrador $t1 armazenou o valor 2*i, pois i + i é 2*i, correto?! Portanto, $t1 agora “vale” 2*i. Se fizermos $t1 + $t1 vamos obter 4*i, pois 2*i + 2*i = 4*i, confere? Usando o mesmo registrador temporário $t1 para armazenar o resultado, de forma a aproveitarmos melhor o uso dos registradores, veja como fica:

 

ADD $t1, $t1, $t1                  # $t1 = $t1 + $t1        $t1 = 2i + 2i = 4i

 

Essas duas linhas são referentes à soma de i até chegar em 4*i, isso garante que o endereço de i esteja correto, não importando o valor que ele contenha. Estamos falando aqui de um array, chamado a, o qual está atribuído ao registrador $s2, portanto, precisamos fazer o cálculo do endereço completo.

 

ADD $t1, $t1, $s2             # $t1 = ( $t1 + $s2 ) = ( 4*i + $s2) que é o mesmo que a[i]

 

Agora sim o cálculo do endereço de a[i] está completo e correto! Toda vez que encontrar um Array com índice variável, lembre-se de que, nesta forma de compilação, ele sempre vai resultar em três linhas de código no Assembly MIPS, as quais são três somas.

 

Da forma como mostrei aqui, o registrador $t1 acaba por ter o comportamento de um registrador acumulador (muitas vezes conhecido como ACC na Arquitetura Intel), que é aquele registrador que realiza operações e armazena resultados, consigo próprio. Agora que o endereço de a[i] já foi calculado, o restante da expressão pode ser compilada da forma que você já conhece, veja:

 

LW $t2,0($t1)                        # $t2 = a[i]

ADD $s0, $s2, $t2                 # g = h + a[i]

 

O código completo fica da seguinte forma:

 

ADD $t1, $s3, $s3      # 2*i

ADD $t1, $t1, $t1      # 4*i

ADD $t1, $t1, $s2      # a[i] = (4*i + $s2)

LW $t2, 0($t1)           # $t1 = a[i]

ADD $s0, $s1, $t2      # g = h + a[i]

 

Para essa instrução, g = h + a[i], e com esta forma de compilação, o código resultante em MIPS é de cinco linhas. Tente agora fazer a compilação para linguagem de máquina, representação e código de máquina.

 

2 - Usar a operação de deslocamento lógico à esquerda

 

Nesta forma de compilação não usamos a soma de forma a simular uma multiplicação. Ao invés disso, usamos a operação SLL, a qual gera o mesmo resultado que uma multiplicação por 2i. O deslocamento à esquerda de 2 bits multiplica por 22, ou seja, 4. A compilação ficará da seguinte forma:

 

SLL $t1, $s3, 2           # $t1 = 4*i

 

Na forma anterior precisamos de duas linhas para chegar no 4*i, já com a SLL uma única linha já nos fornece o resultado almejado. Ainda é preciso calcular o resto do endereço, somando $t1 com a base do Array a:

 

ADD $t1, $t1, $s2                # $t1 = ( $t1 + $s2 ) = ( 4*i + $s2) que é o mesmo que a[i]

 

O restante da compilação permanece o mesmo, veja:

 

LW $t2, 0($t1)           # $t1 = a[i]

ADD $s0, $s1, $t2      # g = h + a[i]

 

Usando SLL conseguimos diminuir em UM (1) a quantidade de linhas do código compilado em ASSEMBLY, o que não quer dizer que esse trecho de código será executado mais rapidamente. Nem sempre quantidade de linhas é sinônimo de execução rápida, as vezes com mais linhas a execução é mais rápida, as vezes não, e, as vezes em menos linhas a execução é mais rápida, as vezes não. Isso depende de uma série de outros fatores. Voltarei a falar sobre isso em artigos próximos, por hora, fica a reflexão! O código completo fica assim:

 

SLL $t1, $s3, 2           # 4*i

ADD $t1, $t1, $s2      # a[i] = (4*i + $s2)

LW $t2, 0($t1)           # $t1 = a[i]

ADD $s0, $s1, $t2      # g = h + a[i]

 

Tente fazer o restante da compilação: linguagem de máquina, representação e código de máquina.

 

 

Conclusão

 

Neste artigo você aprendeu a compilar uma instrução de alto nível com Array de índice variável, para um trecho de código em linguagem Assembly MIPS. Você pode também escolher o método para fazer isso. Não entendeu alguma coisa? Por favor, deixe aqui nos comentários que eu tentarei responder o mais breve possível. Obrigada leitor! Até o próximo artigo.

 

Saiba mais

 

SiFive lança o primeiro SoC RISC-V compatível com Linux

FE310G: Um microcontrolador open source - Interrupções no RISC-V

FE310G: Um microcontrolador open source - Estrutura básica do RISC-V

Outros artigos da série

<< Operandos Imediatos e Constantes no MIPSTestando as instruções MIPS no MARS >>
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