Invocazione di funzioni Passaggio parametri Creazione record di attivazione (anche chiamato stack frame o area di attivazione)
Passaggio parametri F(a,b,c) { } Z = g(x, y, z) Record di attivazione o registri Record di attivazione o registri Usare registri in input puo implicare il salvataggio di tali registri se si invocano altre funzioni innestate. Usare registri in output puo implicare un salvataggio da parte di chi chiama (caller)
Passaggio parametri In questa lezione tratteremo il passaggio parametri via record di attivazione (sia in ingresso che in uscita) Riserveremo un opportuno spazio nel record di attivazione per tali parametri
Record di attivazione Altre variabili Variabili blocchi innestati C (FP) Salvataggio registri usati Record di attivazione (stack frame) composto da: Variabili locali Prev. stack frame pointer Ind. Rit. Par. in ingresso g(r,s,t) chiama FP Prev. FP Record di attivazione g SP SP f(a,b,c) FP Record di attivazione f Records funzioni precedenti SP
Struttura di una chiamata a funzione (M68K) Main() { r=f(a,b,c) } f(a,b,c) { int x,y; return d; } d viene salvato al posto di c (nel record di attivazione di f) al ritorno dalla funzione Posiziona mento parametri a,b,c nel record di attivazione di f Salto ad f Creazione spazio per x, y sul record di attivazione Salvataggio altre info temporane sul record di attivazione Main f
Chiamata/ritorno da sottoprog. Chiamata BSR (branch to subroutine) salto vicino JSR (jump to subroutine) salto lontano Ritorno SP [SP] 4 [SP] [PC] PC i.e. dest. RFS (return from subroutine) PC [[SP]] SP [SP] + 4 41
Record di attivazione int f (int p, int q) { } int a; int b;... return... A7 (o SP) A6 (o FP) = i i - i - 12 i - 8 i - 4 i i + 4 i + 8 i + 12 area della funzione f idem eventuali altri registri eventuale registro salvato variabile locale b variabile locale a puntatore al record del chiamante indirizzo di rientro al chiamante parametro p parametro q area del chiamante 42
Gestione record di attivazione // chiamante... // impila parametri // funzione int f (int p, int q) { int a; // dich. } int b; // dich.... // elabora return... // uscita tab. dei sim. p 8 Q 12 F: LINK FP, #-8 P: EQU 8 // spi. par. p Q: EQU 12 // spi. par. q A: EQU -4 // spi. var. a B: EQU -8 // spi. var. b... // elabora... // sovrascrive Q UNLK FP RFS EQU dichiara il simbolo senza riservare spazio di memoria; lo spazio viene riservato dal chiamante (impilando i parametri) e da LINK (nella funzione) A -4 B -8 43
Riassumendo I record di attivazione formano una lista concatenata Creazione del record: LINK A6, # N (N è la dimensione delle variabili locali) Deallocazione del record: UNLK A6 I parametri sono allocati in ordine inverso hanno spiazzamento positivo rispetto a FP le variabili locali hanno spiazzamento negativo rispetto a FP
Schema di sottoprogramma SUB1: LINK A6, #-N // riservo spazio per le var locali di SUB1 MOVEM.L D1-...,-(SP) // salvo i registri che uso... // preparazione a chiamata di un altra funzione con due parametri MOVE.L..., -(SP) // push secondo parametro MOVE.L..., -(SP) // push primo parametro BRS SUB2 // chiamata ADDA.L #4, SP // pop (n-1)parametri * dim parametri MOVE.L (SP)+,... // spilo e uso il valore in uscita di SUB2 // sovrascritto al primo parametro... MOVE.L..., spiaz.(a6) // salvo in stack il valore restituito da SUB1 in posizione (+4 per ind.rit. + 4(n), n numero di parametri, 4 dim parametri) rispetto a FP MOVEM.L (SP)+,D1-... // ripristino i registri UNLK A6 // elimino var. locali RTS // ritorno al chiamante 45
Conversione espressioni
Albero sintattico Esempio di statement C: Z=(A+B)*(C-D)+5 ALBERO SINTATTICO Z * = + + 5 A B C D
Albero intermedio annotato con loads e stores Z store legenda Risultato temporaneo Contenuto in un registro Valore di una variabile In memoria + * + 5 load load load load Ipotesi variabili globali A B C D
Tile Ogni istruzione e rappresentabile come un tile, il quale ha una forma ad albero. E un pattern MOVE Da, indirizzo_var indirizzo_var (globale) store tile Da
Altro esempio di tile Da MOVE indirizzo_var, Da load tile indirizzo_var
Altro esempio di tile Operazioni binarie aritmetiche (ADD, MUL, SUB etc.) SUB Da, Db (Db-Da) Db Db Da SUB #cost, Da ATTENZIONE ALL ORDINE OPERANDI Da Da cost
Instruction selection Copertura totale dell albero con i tile delle istruzioni a disposizione Z store * + + 5 load load load load A B C D
Allocazione dei registri Allocare i registri associati alle load I registri associati ai trasferimenti temporanei sono bloccati D1 D2 Z store D2 * D2 + + 5 D0 D1 D2 D3 load load load load A B C D
Generazione del codice Visitare l albero in post ordine Scegliere sempre strada a sinistra Ultima volta che si esce dal nodo numerarlo e generare istruzione Z store * + + 5 load load load load A B C D
Codice generato MOVE.L A, D0 MOVE.L B, D1 ADD.L D0, D1 MOVE.L C, D2 MOVE.L D, D3 SUB.L D3, D2 MULS D1, D2 ADD.L #5, D2 MOVE.L D2, Z D2 Z store D2 D1 * D2 + + 5 D0 D1 D2 D3 load load load load A B C D
Chiamate di funzioni Il tile associato ad una chiamata di funzione (passaggio via record di attivazione) Dc funzione(x,y,z) Da Db Dc MOVE.L Dc, -(A7) MOVE.L Db, -(A7) MOVE.L Da, -(A7) BSR Funzione ADDA #8, A7 MOVE.L (A7)+, Dc