Pregunta

Necesito convertir mi código del puntero de pila para usar solo el puntero de marco, ¿cómo puedo hacerlo?Soy muy nuevo en MIPS.

Tengo este código C de recursividad y su código MIPS a continuación.Estoy usando un puntero de pila. ¿Cómo puedo cambiarlo para usar el puntero de marco?

aquí está mi código C

int fact(int n)
{
    if(n!=1)
     return n*factorial(n-1);
}

    int comb (int n, int k)
    {
    return fact (n) / fact (k) / fact (n - k);
    }

aquí mi código MIPS

comb:           
 sub $sp, $sp, 16
 sw $ra , 0($sp)
 sw $s0, 4($sp) 
 sw $a0, 8($sp) 
 sw $a1, 12($sp)
 jal fact       
 move $s0, $v0  
 lw $a0, 12($sp) 
 jal fact       
 div $s0, $s0, $v0 
 lw $a0, 8($sp) 
 lw $a1, 12($sp) 
 sub $a0, $a0, $a1 
 jal fact       
 div $s0, $s0, $v0 
 move $v0, $s0  
 lw  $ra, 0($sp) 
 lw  $s0, 4($sp) 
 addi $sp, $sp, 16 
 jr $ra         
¿Fue útil?

Solución

Los comentarios de @markgz me parecieron interesantes.Su enlace a Wikipedia incluye la cita:

El puntero de marco ($30) es opcional y en la práctica rara vez se usa, excepto cuando la asignación de pila en una función se determina en tiempo de ejecución, por ejemplo, llamando a alloca().

Siempre pensé que $fp Parecía superfluo, pero siempre lo usé de todos modos porque así me enseñaron a hacerlo.

De todos modos, si todavía estás interesado, así es como utilicé el puntero de marco:

#save $ra $s0, $a0 on stack
addi $sp $sp -4
sw   $fp 0($sp)
move $fp $sp
addi $sp $sp -12
sw   $ra  -4($fp)
sw   $a0  -8($fp)
sw   $s0 -12($fp)

...

#restore and shrink stack
lw $s0 -12($fp)
lw $ra  -4($fp)
lw $fp   0($fp)
addi $sp $sp 16

jr $ra

Entonces, cada vez que se expande la pila, uso el puntero de la pila para guardar el valor anterior del puntero del marco y luego restauro el valor anterior del puntero del marco cuando reduzco la pila.

Principalmente copio y pego este código cada vez que escribo una nueva función.

Otros consejos

Usted debe Nunca Convertir código MIPS para usar el marco puntero en lugar del puntero de la pila, porque eso violaría a MIPS

Ampliación de la respuesta de Konrad Lindenbach:

#save $ra, $s0, $a0, $a1
addi $sp, $sp, -4
sw $fp, 0($sp)
move $fp, $sp
addi $sp, $sp, -16
sw $ra, -4($fp)
sw $a0, -8($fp)
sw $a1, -12($fp)
sw $s0, -16($fp)


#Your Code Here


#Restore
lw $s0, -16($fp)
lw $ra, -4($fp) #Can Be C+P'd from here down
addi $sp, $fp, 4
lw $fp, 0($fp)

ja $ra

De esta manera es mucho más fácil de leer y escribir sin sacrificar la longitud de la instrucción.Utilizaría este método para la asignación de memoria dinámica, ya que el fragmento de restauración no necesita saber cuánto se asignaron los datos a la pila.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top