Compilando o comando FOR no MIPS

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

Olá pessoal! Hoje vou mostrar para vocês como codificar, em Assembly MIPS, o comando de controle FOR. Primeiro mostro um código em C, o qual será usado como base de raciocínio lógico. No MARS, usaremos essa lógica para a codificação. Neste exemplo vamos colocar em prática praticamente tudo o que já aprendemos durante esses três anos de caminhada! Vou fazer passo a passo para o entendimento ficar mais fácil, comentando blocos de código. Se você tiver dúvidas a respeito das instruções, sugiro consultar os artigos anteriores, para verificar se consegue por eles é possível resolver. Caso não consiga mesmo entender, deixe sua dúvida nos comentários tá bom. Prontos para mais este desafio?

 

Código em C

 

 

Codificando em Assembly MIPS

 

O primeiro passo é definirmos os dados que vamos usar no programa Assembly:

 

 

No espaço de dados defino dois Labels, um LS para o texto que será impresso no console para a soma, e LM para o texto da média. Em seguida defino um vetor de 5 elementos com os valores de 0 a 4. Escolhi assim para ficar mais fácil acompanhar o cálculo na execução do MARS e corrigir possíveis erros. Depois começamos o espaço do código, definindo o programa principal:

 

 

Feito isto, temos de fazer todas aquelas configurações da pilha do procedimento principal. Então escrevi o label main para identificar o inicio e as quatro linhas seguintes são referentes a pilha.

 

 

As próximas linhas são referentes às chamadas dos procedimentos.

 

 

Carregamos o vetor para o registrador $a0, que é o primeiro parâmetro do procedimento, usando a instrução la. A instrução jal será executada depois que o procedimento soma terminar. Liberando $v0, conseguimos então chamar na sequencia o procedimento media. Novamente precisamos liberar $v0 copiando seu conteúdo para $a1. As próximas linhas são referentes à impressão no console das strings e dos valores inteiros retornados pelos procedimentos:

 

 

Note que para os dois procedimentos foi necessário replicar código. Para a soma é necessário passar como parâmetro o label $LS e para a média o $LM. Além disso, o resultado da soma será armazenado no registrador $s1, e o da média em $s2, por isso eles são usados na chamada de sistema para impressão de números inteiros. Tome muito cuidado com esses detalhes, é muito fácil confundir labels, registradores, etc. Preste bastante atenção quando estiver fazendo seus próprios códigos. As próximas linhas são referentes à configuração do programa principal.

 

 

Agora vamos ver o procedimento da soma, que tem um for para fazer a soma de todos os elementos do vetor. Primeiro defini um label para o procedimento, chamado soma, e em seguida fiz todas as configurações da pilha de procedimento. Nunca se esqueça deles!!! Esse trecho de código você sempre pode utiliza-lo como padrão quando usar procedimentos.

 

 

Próximo passo é carregar o vetor para ser usado no procedimento, assim como definir um registrador para guardar o número total de elementos ($s3) no vetor e outro que guardará a soma ($s1). Esses registradores serão usados no FOR.

 

 

Chegamos na parte que é novidade, como codificar o FOR no MIPS. Antes de iniciar a parte do código referente ao LOOP, precisamos definir i = 0. O registrador que usarei para isto será o $s0. Assim, movi o valor zero, que está no registrador $zero, para $s0. Pronto, a variável i foi inicializada com zero, lembrando que o nosso i é o índice do vetor.

 

 

Feito isto, comecemos o LOOP. O FOR é uma estrutura de controle como o WHILE e o DO-WHILE. Para escolher para onde ir, vamos precisar usar a instrução SLT juntamente com a BEQ, como já estudamos antes. Essas duas linhas também podem ser usadas como um padrãozinho toda vez que você for codificar um LOOP FOR. A instrução SLT verifica se i >= n, ou $s0>= $s3, que é a condição de parada aqui. Se for verdade, armazena zero em $t0, caso contrário, armazena 1. Bom, mas a instrução SLT, apenas armazena um valor 0 ou 1, ela não toma nenhuma decisão, então, quem é que faz isso? A instrução BEQ é quem faz esse papel, ela decide continuar, ou não, executando o código dentro do LOOP. Se já alcançamos o final do vetor, então, a execução deve parar (EXIT), mas enquanto não atingirmos o fim do vetor, o bloco deve continuar executando. Assim, se i>=n, sai do LOOP, caso contrário, continua executando.

 

 

Depois de codificar corretamente a instrução FOR, pelo menos a primeira e a segunda parte dele, devemos agora tratar do ARRAY. Jamais se esqueçam do alinhamento de memória usado no MIPS. Temos de fazer aquele cálculo, padrãozinho também, toda vez que usarmos ARRAYs. Assim, usei a instrução SLL para tornar isso mais fácil, ela já faz o cálculo de 4*i juntamente com o registrador que vamos usar, que neste caso, é o $s0 (i). Em seguida, usei o registrador $s2 para armazenar o resultado final do endereço, que é a soma do endereço do vetor com o (4*i). Depois de tudo isso, podemos fazer o carregamento do elemento que está na posição que queremos, e então soma-lo com o valor que está em $s1 (que será a nossa soma final).

 

 

Elemento carregado, somado e resultado guardado. Agora é hora de ir para a próxima posição do vetor. Como fazer isso? No FOR usamos um contador, i +=1, mas e no Assembly? Não é tão difícil ou complicado, só é preciso cuidar com os registradores que devem ser utilizados. Usei a instrução ADDI para somar o valor que está no índice i ($s0), com o imediato 1, assim incrementamos o índice e conseguimos passar para a próxima posição. A instrução J volta para o inicio do LOOP e o label EXIT sai desse bloco de código ao término da execução do LOOP.

 

 

Finalizando o procedimento soma, temos de terminar as configurações referentes aos registradores. Passei $s1 na instrução ADD pois é este registrador que contem o resultado da soma, e que deve retornar ao programa principal. A instrução JR encerra o procedimento.

 

 

O procedimento media é exatamente a mesma coisa, só que mais fácil ainda, pois não há um FOR dentro dele a ser codificado. Dessa forma, as configurações do procedimento devem ser codificadas corretamente. Aqui eu usei a instrução DIV para calcular a média, portanto, $s3 é o numero total de elementos no vetor, e $s1 é a soma calculada no procedimento soma. O resultado é armazenado em $s2, o qual é passado na instrução ADD que retorna ao programa principal.

 

 

Encerrando nosso “programinha” em Assembly MIPS, precisamo encerrá-lo corretamente:

 

 

A seguir você confere o código completo, para facilitar a visualização e também para que você teste em sua máquina.

 

 

 

Conclusão

 

E então pessoal? Acharam muito difícil? Se tiverem dúvidas, deixem aqui nos comentários, que responderei o mais breve possível. Para exercitar um pouco, sugiro vocês criarem mais procedimentos usando vetores. É isso galera, até o próximo artigo.

Outros artigos da série

<< MIPS: 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.

Deixe um comentário

avatar
 
  Notificações  
Notificar