Problemino con codice Assembly per MIPS
Salve a tutti
. Sto studiando per l'esame di Calcolatori Elettronici ed ho scritto una semplice funzione in assembly-Mips che mi copi il contenuto di un array in un altro. Il programma funziona, l'unico problema è che se salvo sullo stack, all'inizio del programma, i registri che andrò ad utilizzare, e poi alla fine li riaggiornerò sempre dallo stack, ricevo un errore di segmentation fault-core dumped. Questo è molto strano perché se i registri non li salvo sullo stack funziona tutto perfetto.
Questo è il codice C che chiamerà la funzione:
Mentre questo è il codice che non funziona e da segmentation fault:
Infine questo è il codice che funziona ma non riesco a spiegarmi perché il caricare e scaricare dati dalla memoria possa dare segmentation fault, e soprattutto perché solo se uso i registri che ho salvato in memoria:
Vi ringrazio in anticipo, Luca
Questo è il codice C che chiamerà la funzione:
- Codice: Seleziona tutto
#include "stdio.h"
void copiaArray(int s [], int z [], int dim){
}
void stampaArray(int a [], int DIM){
printf("Array a:\n");
int i = 0;
while(i < DIM){
printf("a[%d]: %d\n",i,a[i]);
i++;
}
printf("Fine------\n");
}
int main(){
int DIM = 10;
int a[] = {1,4,2,4,6,3,6,8,10,22};
int d[DIM];
copiaArray(a,d,DIM);
printf("Array a:\n");
stampaArray(a,DIM);
printf("Array d:\n");
stampaArray(d,DIM);
return 0;
}
Mentre questo è il codice che non funziona e da segmentation fault:
- Codice: Seleziona tutto
#in $4 ho l'indirizzo del primo array (sorgente), in $5 ho l'indirizzo del
#secondo array (destinazione), ed in $6 ho la loro dimensione (10)
addiu $sp, $sp,-8 #creo uno spazio sullo stack per 2 registri a 32bit
sw $s4, 0($sp) #salvo i due registri che andrò ad utilizzare
sw $s5, 4($sp) #...
add $t0, $zero, $zero #inizializzo t0 come contatore che andrà da 0 a 9
add $s4, $zero, $4 #pongo $s4 all'indirizzo base del primo array
add $s5, $zero, $5 #pongo $s5 all'indirizzo base del secondo array
LOOP1: slt $t1, $t0, $6 #controllo se il contatore ha superato $6=10 e se si salto alla fine
beq $t1, $zero, FINE
lw $t2, 0($s4) #salvo in $t2 un elemento del primo array
sw $t2, 0($s5) #e lo carico nel secondo array
add $s4, $s4, 4 #incremento di una posizione i due contatori degli array
add $s5, $s5, 4
addi $t0, $t0, 1 #incremento il contatore dei 10 giri
j LOOP1 #torno a LOOP1
FINE:
lw $s4, 0($sp) #riporto i valori nei registri dallo stack
lw $s5, 4($sp)
addiu $sp, $sp, 8 #elimino lo spazio che mi ero creato sullo stack
j $31 #ritorno al chiamante
nop
Infine questo è il codice che funziona ma non riesco a spiegarmi perché il caricare e scaricare dati dalla memoria possa dare segmentation fault, e soprattutto perché solo se uso i registri che ho salvato in memoria:
- Codice: Seleziona tutto
#in $4 ho l'indirizzo del primo array (sorgente), in $5 ho l'indirizzo del
#secondo array (destinazione), ed in $6 ho la loro dimensione (10)
addiu $sp, $sp,-8 #creo uno spazio sullo stack per 2 registri a 32bit
sw $s0, 0($sp) #salvo i due registri che vorrei utilizzare ma riceverei segmentation fault ??
sw $s1, 4($sp) #...allora uso $s4 e $s5 che non ho salvato in memoria e funziona tutto...
add $t0, $zero, $zero #inizializzo t0 come contatore che andrà da 0 a 9
add $s4, $zero, $4 #pongo $s4 all'indirizzo base del primo array
add $s5, $zero, $5 #pongo $s5 all'indirizzo base del secondo array
LOOP1: slt $t1, $t0, $6 #controllo se il contatore ha superato $6=10 e se si salto alla fine
beq $t1, $zero, FINE
lw $t2, 0($s4) #salvo in $t2 un elemento del primo array
sw $t2, 0($s5) #e lo carico nel secondo array
add $s4, $s4, 4 #incremento di una posizione i due contatori degli array
add $s5, $s5, 4
addi $t0, $t0, 1 #incremento il contatore dei 10 giri
j LOOP1 #torno a LOOP1
FINE:
lw $s0, 0($sp) #riporto i valori nei registri dallo stack
lw $s1, 4($sp)
addiu $sp, $sp, 8 #elimino lo spazio che mi ero creato sullo stack
j $31 #ritorno al chiamante
nop
Vi ringrazio in anticipo, Luca
