Vetores em Assembly MIPS no QtSpim

Eduardo Lacerda

Você vai aprender

Como operar um vetor em Assembly MIPS para o QtSpim!

Pré-requisitos

Lógica de Programação

Programação Básica em Assembly

Programação em Assembly MIPS no QtSpim

exercício proposto

O objetivo deste tutorial é ensinar a operar vetores em Assembly MIPS para o simulador de assembly QtSpim. Dessa forma, vamos propor o seguinte código em C#

static void Main(string[] args)         
		{             
			int[] theArray = new int[40];

            		int n = 2;

            		theArray[0] = 1;
            		theArray[1] = 1;

            		do
            		{
               			theArray[n] = theArray[n - 1] + theArray[n - 2];
                		n++;
            		} while (n < 40);
		}

Esse programa calcula o valor do quadragésimo termo da Sequência de Fibonacci.

Para saber mais sobre a sequência, acesse:

Sequencia de Fibonacci (Matematicazup)

fragmento de código widget

passo 1: int[] theArray = new int[40];

Abra um editor de texto de sua preferência, pois o QtSpim é apenas um simulador de assembly, e vamos começar...

Para a declaração do vetor, nós temos que alocar um espaço na memória de acordo com o tamanho do nosso vetor. Para isso, vamos declarar o nosso vetor na área de dados.

		.data
		theArray:
		.space 160

O comando .space reserva na memória o espaço necessário para o vetor. Como queremos um vetor com 40 posições, e cada posição ocupa 4 bytes na memória, precisamos então de um espaço de 160 bytes na memória (40 * 4 = 160).

passo 2: int n = 2;

A tarefa agora é declarar uma variável n que vai armazenar as posições n do vetor.

		.text
		main:	addi $t0, $zero, 8

Estamos então começando o nosso programa na área .text e iniciando o programa com a label main. Assim armazenamos em $t0, que será nosso n, o valor 8, que corresponde ao incremento necessário para a posição 2 do vetor.

passo 3: theArray[0] = 1; e thearray[1] = 1;

A tarefa agora é guardar na posição 0 e na posição 1 do vetor, o valor 1.

		addi $t6, $zero, 1
		addi $t7, $zero, 4
		sw $t6, theArray($zero)
		sw $t6, theArray($t7)

Estamos declarando $t6 para armazenar o valor 1 que queremos colocar nas posições 0 e 1 do vetor e o $t7 para armazenar o incremento que será utilizado para "andar" pelo vetor. Ao armazenar um registrador na memória, temos que indicar o endereço da memória onde queremos armazenar o valor, e o incremento para que o nosso vetor esteja ordenado da forma como queremos. Dessa forma estamos armazenando $t6, na posição onde está theArray (já reservado por nós), mais 0 (posição de theArray + 0) e estamos armazenando $t6 de novo, que é o valor 1, na posição theArray + $t7 (posição de theArray + 4).

passo 4: do {} while (n<40);

A tarefa agora é fazer um estrutura de repetição while para calcularmos os valores da sequência

		while: addi $t3, $t0, -8
		addi $t4, $t0, -4		
		lw $t1, theArray($t3)
		lw $t2, theArray($t4)
		add $t5, $t1, $t2
		sw $t5, theArray($t0)
		addi $t0, $t0, 4
		blt $t0, 160, while
		jr $ra	

Nessa parte do código, armazenamos as posições [n-1] e [n-2] nos registradores $t3 e $t4. Depois acessamos as mesmas posições do vetor na memória para pegar os valores lá armazenados e colocamos em $t1 e $t2. O registrador $t5 recebe a soma entre os dois elementos e depois é armazenado na posição n do vetor ($t0). Fazemos um incremento em $t0, para atualizar a posição n, e fazemos a comparação do loop. O comando blt faz um salto para o início do while, se $t0 (posição n do vetor) for menor que 160 (espaço alocado para o vetor). Esse comando funciona como se fosse um slt seguido de um bne. O jr $ra, como já sabemos, faz o retorno da função e finaliza o programa.

passo 5: programa final

Depois de fazer todos os passos, vamos ver como fica o programa final.

		.data                      # indica para o montador a area de dado 
		theArray:		    # rotulo para a area (variavel)	
  		.space 160                # reserva espaco de 160 bytes (40 posicoes de 4 bytes)
  		.text                     # indica inicio do codigo
		main:                       # rotulo do programa principal
  		addi  $t0, $0, 8          # faz n = 2
  		addi  $t6, $0, 1	    # carrega 1 para $t6
  		addi  $t7, $0, 4	    # carrega 4 para $t7
  		sw    $t6, theArray($0)   # grava 1 na posicao Array[0]
  		sw    $t6, theArray($t7)  # grava 1 na posicao Array[1]
		loop:			    # inicio do DO-WHILE	
  		addi  $t3, $t0, -8        # posicao n - 2 
  		addi  $t4, $t0, -4        # posicao n - 1
  		lw    $t1, theArray($t3)  # leitura de Array[n-2]
  		lw    $t2, theArray($t4)  # leitura de Array[n-1]
  		add   $t5, $t1, $t2       # realiza a soma Array[n-1] + Array[n-2]
  		sw    $t5, theArray($t0)  # salva resultado em Array[n]
  		addi  $t0, $t0, 4         # faz n++
  		blt   $t0, 160, loop      # salta para o inicio do loop se $t0 < 160 
  		jr    $ra		    # retorna da funcao

Agora podemos fazer a simulação no QtSPIM, como já fizemos no tutorial anterior.

simulação no QtSpim

Como nosso programa não possui nem um tipo de impressão em console, teremos que ver o resultado na janela dos registradores.

Vetor_QtSpim

Ali podemos ver os valores que os registradores que usamos assumiram até o final do programa. Note também que esses valores estão em hexadecimal.

links úteis

Tutorial de como usar o SPIM 

Este tutorial foi adaptado do tutorial de mesmo título, desenvolvido por Marcel Vinícius!!!


Voltar