40 likes | 191 Views
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
E N D
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