Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Problemino con codice Assembly per MIPS

Linguaggi e sistemi

Moderatori: Foto UtentePaolino, Foto Utentefairyvilje

0
voti

[1] Problemino con codice Assembly per MIPS

Messaggioda Foto UtenteLuca1995 » 26 giu 2015, 11:10

Salve a tutti :D . 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:
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
Avatar utente
Foto UtenteLuca1995
790 2 6 12
Frequentatore
Frequentatore
 
Messaggi: 200
Iscritto il: 6 gen 2013, 23:17

0
voti

[2] Re: Problemino con codice Assembly per MIPS

Messaggioda Foto Utentesimo85 » 26 giu 2015, 12:52

Ciao !

Luca1995 ha scritto: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:


Un segmentation fault, se non sbaglio :D , è sempre un errore dovuto ad un accesso di memoria non lecito.

Nel tuo codice scrivi:

Codice: Seleziona tutto
addiu    $sp, $sp, -8   #creo uno spazio sullo stack per 2 registri a 32bit


Sicuro che quel 8 sia giusto ? Non dovrebbe essere 64 ? *

Non conoscendo e non avendo esperienza con l'Assembly MIPS (anche se mi piace molto la programmazione a basso livello), ho cercato qualcosina. Qui hai un esempio in cui si usa lo stack.

* EDIT:
Forse li ho frainteso. :(
Dato che dovrebbe essere il numero in byte quindi dovrebbe essere giusto 8.
sorry
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

1
voti

[3] Re: Problemino con codice Assembly per MIPS

Messaggioda Foto UtenteDanteCpp » 26 giu 2015, 13:33

hai provato a togliere la u da addiu?

EDIT:
mi sembra strano che funzioni l'istruzione j $31, non si dovrebbe usare jr $31?
Avatar utente
Foto UtenteDanteCpp
4.730 3 9 13
Master EY
Master EY
 
Messaggi: 1106
Iscritto il: 15 dic 2011, 18:51

1
voti

[4] Re: Problemino con codice Assembly per MIPS

Messaggioda Foto UtenteLuca1995 » 28 giu 2015, 21:28

Cavolo, era proprio la cattivissima u di addiu che chiaramente, oltre a non allocare nuovo spazio, mi deallocava quello usato anche da altre procedure. Che rinco che sono :oops: :oops:
Vero anche del ritorno con jr, anche se non mi dava un errore esplicito ma sono un warning
Grazie a tutti, ora sono più tranquillo :D
Avatar utente
Foto UtenteLuca1995
790 2 6 12
Frequentatore
Frequentatore
 
Messaggi: 200
Iscritto il: 6 gen 2013, 23:17


Torna a PC e informatica

Chi c’è in linea

Visitano il forum: Nessuno e 9 ospiti