PDA

Visualizza la versione completa : Programmazione assembler del MIPS


Bombonera
14-11-2014, 16:42
Ciao a tutti.

Non ho capito perché bisogna salvare un registro nella memoria e poi ripristinarlo. So che i dati vengono conservati in memoria quando questi ultimi fanno parte di una struttura dati, come ad esempio un vettore di elementi. Spostiamo i valori nella memoria perché i registri sono limitati. Ma non ho capito il perché si usa questa tecnica anche in questo programma:

int esempio_foglia( int g, int h, int i, int j) {

int f;

f = (g + h) - (i + j);
return f;
}

Il libro praticamente aggiorna lo stack pointer per far spazio ad un elemento in memoria. Questo elemento è f. In pratica salva f nello stack (pila) e poi a fine funzione lo ripristina. Non ho capito perché il valore deve essere salvato e poi ripristinato e poi perché proprio f ?

Se non avete capito la domanda ditemelo.

Grazie.

oregon
14-11-2014, 17:04
In effetti non ho capito ... puoi mostrare il codice assembler a cui ti riferisci?

Bombonera
14-11-2014, 17:48
In effetti non ho capito ... puoi mostrare il codice assembler a cui ti riferisci?

Assumiamo f = $s0

addi $sp, $sp, -4 # aggiornamento $sp (faccio spazio di 1 elemento)
sw $s0, 0($sp) # salviamo $s0 su stack

......

lw $s0 0($sp) # ripristina $sp
addi $sp $sp 4 # ripristina $sp

Bombonera
14-11-2014, 17:50
Insomma perché prima dell'esecuzione della funzione bisogna salvare $s0 e ripristinarlo al termine della funzione ?

oregon
14-11-2014, 18:05
Insomma perché prima dell'esecuzione della funzione bisogna salvare $s0 e ripristinarlo al termine della funzione ?

Semplicemente perché $s0 viene usato all'interno della funzione per la variabile locale e quindi il suo valore all'ingresso della funzione deve essere preservato. In caso contrario $s0 all'uscita sarebbe "sporcato" con il valore della variabile locale.

Bombonera
14-11-2014, 19:23
Semplicemente perché $s0 viene usato all'interno della funzione per la variabile locale e quindi il suo valore all'ingresso della funzione deve essere preservato. In caso contrario $s0 all'uscita sarebbe "sporcato" con il valore della variabile locale.

Nei linguaggi ad alto livello questo avviene automaticamente.

Ti ringrazio. :-)

M.A.W. 1968
14-11-2014, 22:10
Il meccanismo illustrato dal nostro ottimo Oregon si chiama, in generale, register preservation o register saving e fa parte del "contratto" implicito tra il chiamante e la subroutine. Per questo molti set di istruzioni (ISA) prevedono apposite istruzioni dedicate, come la coppia PUSHA/POPA del mondo x86 o le istruzioni di shadowing sugli Hitachi di fascia alta.

Si noti che in molti sistemi legacy (es. DOS, ma anche nei BIOS classici) la RP non è quasi mai garantita. Inoltre non è raro trovare che, nelle varie versioni, alcune subroutine "sporcano" in modo non documentato taluni registri, principalmente per risparmiare una manciata di istruzioni (PUSHA/POPA non esistevano sui primi x86, e sono comunque inerentemente lente): il che è doppiamente problematico su architetture tendenzialmente CISC e quindi povere di registri come x86.

Loading