( \mathbf{1 0} pontos) Escreva um código em linguagem de montagem de processador MIPs equivalentes aos códigos em C abaixo:
#define n 500
int main()
{
    int vetor[n];
    int i,sum;
    sum=0;
    for( i=0; i<n; i++)
    {
        vetor[i] = i;
    }
    for( i=0; i<250; i++)
    {
        vetor[i] = vetor[i]+vetor[n-i];
    }
}

Passo 1

O enunciado pede para converter o seguinte trecho em C:
#define n \(500\)
int main()
{
    int vetor[n];
    int i,sum;
    sum \(=0\);
    for (i \(=0\); i < n; i\(++\)) {
        vetor[i] \(=\) i;
    }
    for (i \(=0\); i < \(250\); i\(++\)) {
        vetor[i] \(=\) vetor[i] \(+\) vetor[n - i];
    }
}
em código MIPS. Vamos alocar o array vetor ( 500 inteiros =2000 bytes) na pilha, usar registradores preservados ( \$s_0 para i, \$s_1 para sum) e registradores temporários ( \$t_0 \$t_4) para os cálculos de endereço e soma.

Passo 2

Montamos o stack frame reservando 2016 bytes ( 2000 para vetor +16 para salvar \(ra, \)s\(0\) e \(s\(1\), alinhado a 16 bytes). Guardamos \)ra, \(s\(0\) e \)s\(1\) no início do frame. A base de vetor fica em \(16\)($sp).

Passo 3

Inicializamos sum \(=0\) em \(s\(1\) e i \(=0\) em \)s\(0\), depois fazemos o primeiro loop de 0 até 499 armazenando em cada posição de vetor o valor de i:
    li   $s\(1,0\)         # sum \(=0\)
    li   $s\(0,0\)         # i \(=0\)
loop\(1\):
    bge  $s\(0,500\),endloop\(1\)
    sll  \(t\(0\),\)s\(0,2\)     # $t\(0=\) i * \(4\)
    add  \(t\(0\),\)t\(0\),$sp
    addi \(t\(0\),\)t\(0,16\)    # $t\(0=\) endereço de vetor[i]
    sw   \(s\(0,0\)(\)t\(0\))    # vetor[i] \(=\) i
    addi \(s\(0\),\)s\(0,1\)
    j    loop\(1\)
endloop\(1\):

Passo 4

Reiniciamos i \(=0\) em $s\(0\) e fazemos o segundo loop de 0 até 249: carregamos vetor[i], carregamos vetor[n-i] com n \(=500\), somamos e armazenamos de volta em vetor[i].
    li   $s\(0,0\)         # i \(=0\)
loop\(2\):
    bge  $s\(0,250\),endloop\(2\)
    # endereço de vetor[i]
    sll  \(t\(0\),\)s\(0,2\)
    add  \(t\(0\),\)t\(0\),$sp
    addi \(t\(0\),\)t\(0,16\)
    lw   \(t\(1,0\)(\)t\(0\))    # $t\(1=\) vetor[i]
    # calcula índice n - i em $t\(2\)
    li   $t\(2,500\)
    sub  \(t\(2\),\)t\(2\),\(s\(0\)   #\)t\(2=500\) - i
    sll  \(t\(2\),\)t\(2,2\)
    add  \(t\(2\),\)t\(2\),$sp
    addi \(t\(2\),\)t\(2,16\)    # $t\(2=\) endereço de vetor[\(500\)-i]
    lw   \(t\(3,0\)(\)t\(2\))    # $t\(3=\) vetor[\(500\)-i]
    add  \(t\(4\),\)t\(1\),\(t\(3\)   #\)t\(4=\) vetor[i] \(+\) vetor[\(500\)-i]
    sw   \(t\(4,0\)(\)t\(0\))    # vetor[i] \(=\) $t\(4\)
    addi \(s\(0\),\)s\(0,1\)
    j    loop\(2\)
endloop\(2\):

Passo 5

Restauramos os registradores salvos, ajustamos a pilha e retornamos:
    lw   \(s\(1,8\)(\)sp)
    lw   \(s\(0,4\)(\)sp)
    lw   \(ra,\(0\)(\)sp)
    addi \(sp,\)sp,\(2016\)
    jr   $ra

Resposta

.data
.text
.globl main
main:
addi sp,sp,- 2016 # reserva frame
sw ra,\(0()sp) # salva $ra
sw s\(0,4()sp) # salva $s 0 (índice i)
sw s\(1,8()sp) # salva $s 1 (sum)
li   $s\(1,0\)           # sum \(=0\)
li   $s\(0,0\)           # i \(=0\)
loop 1:
bge s\(0,500\),endloop\(1\) sll \(t\(0\),\)s\(0,2\) add \(t\(0\),\)t\(0\),sp
addi t\(0,)t 0,16
sw s\(0,0()t 0) # vetor[i] = i
addi s\(0,)s 0,1
j loop 1
endloop 1:
li   $s\(0,0\)           # i \(=0\)
loop 2:
bge s\(0,250\),endloop\(2\) sll \(t\(0\),\)s\(0,2\) add \(t\(0\),\)t\(0\),sp
addi t\(0,)t 0,16
lw t\(1,0()t 0) # $t 1= vetor[i]
li   $t\(2,500\)
sub  \(t\(2\),\)t\(2\),$s\(0\)     # t\(2=500\) - i
sll  \(t\(2\),\)t\(2,2\)
add  \(t\(2\),\)t\(2\),$sp
addi \(t\(2\),\)t\(2,16\)
lw   \(t\(3,0\)(\)t\(2\))      # $t\(3=\) vetor[\(500\)-i]

add  \(t\(4\),\)t\(1\),\(t\(3\)     #\)t\(4=\) vetor[i] \(+\) vetor[\(500\)-i]
sw   \(t\(4,0\)(\)t\(0\))      # vetor[i] \(=\) $t\(4\)
addi \(s\(0\),\)s\(0,1\)
j    loop\(2\)
endloop 2:
lw   \(s\(1,8\)(\)sp)      # restaura $s\(1\)
lw   \(s\(0,4\)(\)sp)      # restaura $s\(0\)
lw   \(ra,\(0\)(\)sp)      # restaura $ra
addi \(sp,\)sp,\(2016\)    # libera frame
jr   $ra             # retorna de main

Exercícios relacionados