Convenzioni chiamate a procedure Riassunto Pratico
Procedura A chiama la procedura B Prima che la procedura A chiami la procedura B Ho bisogno di utilizzare qualche registro $s? Devo salvare il valore del registro $s nello stack prima di sovrascriverlo Ho qualche valore nei registri $t che mi interessa mantenere anche dopo la chiamata alla procedura B? Si -> devo salvare il valore contenuto in questi registri (dato che i $t possono essere sovrascritti dalla procedura B senza nessun tipo di salvataggio) Copio il valore contenuto in questi registri nei registri $s (che non possono essere sovrascritti dalla procedura B) Oppure salvo il valore di questi registri nello stack Devo salvare nello stack il valore del registro $ra (che contiene l’indirizzo di ritorno della procedura A) dato che verrà sovrascritto nel momento in cui chiamo la procedura B (con l’istruzione jal) Devo passare qualche parametro alla procedura B? Si, ma sono meno di 5 Inserisco i valori da passare nei registri $a Si, ma sono più di 4 Inserisco i primi 4 valori da passare nei registri $a Alloco n parole (n = numero di parametri da passare alla procedura B – 4) nello stack per i rimanenti parametri e inserisco i valori da passare Devo allocare 4 parole nello stack per la procedura B (questo è un “dovere” dovuto alle convenzioni usate) Chiamo la procedura B (jal B) Ritorno dalla procedura B La procedura B mi deve passare qualche valore di ritorno Si -> muovo i valore/i di ritorno contenuto/i nei registri $v in un registro diverso ($t generalmente) Ho salvato qualche registro $t prima della chiamata alla procedura perché mi interessava il suo valore? Si -> devo ripristinare il valore precedentemente salvato nello stack Termine della procedura A Ho utilizzato qualche registro $s? Si -> Ripristino il valore precedente dei registri $s che ho precedentemente salvato nello stack Ripristino il valore del registro $ra precedentemente salvato nello stack (perché sarà stato sovrascritto nel momento della chiamata alla procedura B) DeAlloco lo stack Salto alla procedura padre (jr $ra)
Procedura A chiama la procedura B Ho bisogno di utilizzare qualche registro $s? Devo salvare il valore del registro $s nello stack prima di sovrascriverlo E’ una procedura non foglia Ho qualche valore nei registri $t che mi interessa mantenere anche dopo la chiamata alle altre procedure? Si -> devo salvare il valore contenuto in questi registri (dato che i $t possono essere sovrascritti dalle altre procedure senza nessun tipo di salvataggio) Copio il valore contenuto in questi registri nei registri $s (che non possono essere sovrascritti dalle altre procedure) Oppure salvo il valore di questi registri nello stack Devo salvare nello stack il valore del registro $ra (che contiene l’indirizzo di ritorno alla procedura A) dato che verrà sovrascritto nel momento in cui chiamo le altre procedure (con l’istruzione jal) Devo passare qualche parametro alle altre procedure? (se chiamo più di una procedura tengo in considerazione la procedura che richiede più parametri) Si, in generale Devo salvare i registri $a che contengono i parametri passati dalla procedura A alla procedura B (perché verranno sovrascritti dai parametri da passare elle altre procedure) Li salvo nello stack della procedura A (rispettivamente nelle 4 parole allocate da quest’ultima per convenzione) Si, ma sono meno di 5 Inserisco i valori da passare nei registri $a Si, ma sono più di 4 Inserisco i primi 4 valori da passare nei registri $a Alloco n parole (n = numero di parametri da passare alla procedura che richiede più parametri – 4) nello stack per i rimanenti parametri e inserisco i valori da passare Devo allocare 4 parole nello stack per le altre procedure (questo è un “dovere” dovuto alle convenzioni usate) Chiamo le altre procedure (jal …) Ritorno dalle procedure Le procedure mi devono passare qualche valore di ritorno Si -> muovo i valore/i di ritorno contenuto/i nei registri $v in un registro diverso ($t generalmente) Ho salvato qualche registro $t prima della chiamata alle procedure perché mi interessava il suo valore? Si -> devo ripristinare il valore precedentemente salvato nello stack Termine della procedura B Ho utilizzato qualche registro $s? Si -> Ripristino il valore precedente dei registri $s che ho precedentemente salvato nello stack Ripristino il valore del registro $ra precedentemente salvato nello stack (perché sarà stato sovrascritto nel momento della chiamata alle altre procedure) Inserisco nei registri $v gli eventuali valori di ritorno per la procedura A DeAlloco lo stack Salto alla procedura padre (jr $ra)
Nota Attenzione: Lo stack va allocato all’inizio delle varie procedure e non può essere più modificato fino alla fine della procedura Conviene fare prima i conti di quante parole vi serviranno all’interno della procedura e poi scrivere le istruzioni all’inizio della procedura necessarie per allocare lo spazio richiesto Lo stack va de-allocato alla fine della procedura Lo stak deve essere allocato a multipli di 2 parole Eventualmente aggiungere una parola vuota di riempimento