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çõesPonto Flutuante no MIPS >>
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Hardware » Compilando o comando FOR no MIPS
Comentários:
Notificações
Notificar
guest
0 Comentários
Inline Feedbacks
View all comments
Talvez você goste:

Séries



Outros da Série

Menu

WEBINAR
 
NVIDIA JETSON – A Inteligência Artificial na palma de sua mão

Data: 08/07 às 14:00h Apoio: Arrow | NVIDIA
 
INSCREVA-SE AGORA »



 
close-link

WEBINAR
 
Redes Mesh para Monitoramento
e Controle de Sensores

Data: 15/07 às 14:00h Apoio: Artimar| Microchip| Tecsus
 
INSCREVA-SE AGORA »



 
close-link