• Non ci sono risultati.

Pila di Attivazione

N/A
N/A
Protected

Academic year: 2021

Condividi "Pila di Attivazione"

Copied!
18
0
0

Testo completo

(1)

G. Mecca – Università della Basilicata – mecca@unibas.it

Programmazione Procedurale in Linguaggio C++

Sottoprogrammi Concetti Avanzati Pila di Attivazione

versione 2.5

Questo lavoro è concesso in uso secondo i termini di una licenza Creative Commons (vedi ultima pagina)

Sommario

m

Pila di Attivazione

ðRecord di Attivazione

m

Funzionamento del Compilatore

m

La Ricorsione

Sottoprogrammi: Concetti Avanzati >> Sommario

(2)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 3

Pila di Attivazione

m

In questa parte

ðapprofondimenti sul funzionamento e sulla gestione della memoria nelle applicazioni

m

Argomento particolarmente importante

ðchiarisce il concetto di stato di un programma ðchiarisce il funzionamento del compilatore ðconsente di affrontare l’utilizzo del

“debugger” (o correttore)

4

Pila di Attivazione

m

Compiti del compilatore e del collegatore

ðgenerare il codice eseguibile a partire dal

codice sorgente

m

Codice eseguibile

ðdeve eseguire le istruzioni dell’applicazione ðeffettuare le chiamate dei sottoprogrammi ðgestire l’allocazione di memoria per i moduli ðgestire le regole di visibilità

Sottoprogrammi: Concetti Avanzati >> Pila di Attivazione

(3)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 5

Pila di Attivazione

m

Come viene gestito questo processo ?

ðutilizzando un algoritmo standard

ðbasato su una precisa strategia di gestione della memoria

m

Memoria per un’applicazione

ðdivisa in due zone

ðmemoria per il codice macchina ðmemoria per i dati

ðesiste una terza zona (“heap”) >>

Pila di Attivazione

m

Memoria per il codice

ðcodice oggetto compilato (linguaggio macchina) a partire dal codice sorgente ðogni istruzione sorgente corrisponde ad un

blocco di istruzioni di codice macchina

ðil codice oggetto opportunamente collegato, viene caricato in memoria all’esecuzione ðogni istruzione in linguaggio macchina

occupa un registro della memoria

Sottoprogrammi: Concetti Avanzati >> Pila di Attivazione

(4)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 7

Esempio:

Equazioni di II Grado

istruzioni del codice sorgente (discriminante)

istruzioni corrispondenti in codice macchina

indirizzi della memoria

8

Pila di Attivazione

m

Esecuzione delle istruzioni

ðviene effettuata attraverso opportuni registri del processore

ð“program counter”: registro che contiene l’indirizzo di memoria della prossima istruz.

ð“registro istruzione”: registro che contiene il codice binario dell’istruzione da eseguire ðregistri dati: registri utilizzati per gli operandi

Sottoprogrammi: Concetti Avanzati >> Pila di Attivazione

(5)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 9

Pila di Attivazione

m

Memoria per i dati

ðvista informalmente negli esempi

ðpiù precisamente, corrisponde alla “pila di attivazione”

m

Pila di attivazione (“Program Stack”)

ðspazio della memoria dedicato all’esecuzione di un programma

ðcontiene tutte le informazioni necessarie al processore per gestire l’esecuzione del prog.

Pila di Attivazione

m

Perché pila ?

ðla memoria viene gestita come una pila di piatti (rovesciata)

ðper ogni nuovo modulo eseguito, la memoria viene disposta come un nuovo piatto sulla pila (in fondo alla pila)

ðgli spazi vengono rilasciati nell’ordine in cui compaiono nella pila

ðla struttura di dati è una pila di record

Sottoprogrammi: Concetti Avanzati >> Pila di Attivazione

(6)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 11

Pila di Attivazione

m

Inizialmente

ðviene riservato un primo blocco di memoria per gli eventuali dati globali (dati dichiarati a livello di file)

ðsuccessivamente viene eseguito il main, e riservato lo spazio di memoria corrispondente ðpoi vengono eseguite le eventuali chiamate

successive, secondo la semantica descritta

12

Esempio: Istruzioni di II Grado

Sottoprogrammi: Concetti Avanzati >> Pila di Attivazione

memoria per il main memoria per leggiDatiEquazione

(a1, b1, c1) memoria per leggiDatiEquazione

(a2, b2, c2) memoria per stampaDatiEquazione

(a1, b1, c1) memoria per stampaDatiEquazione

(a2, b2, c2) memoria per discriminante (a1, b1, c1) memoria per discriminante (a2, b2, c2) memoria per discriminante (a1, b1, c1) memoria per discriminante (a2, b2, c2) memoria per primaRadiceReale

(a1, b1, c1) memoria per primaRadiceReale

(a2, b2, c2) memoria per discriminante (a1, b1, c1) memoria per discriminante (a2, b2, c2) memoria per secondaRadiceReale

(a1, b1, c1) memoria per secondaRadiceReale

(a2, b2, c2)

Memoria RAM memoria per i

dati globali (vuota in questo caso)

analogo ad una pila di 4 piatti

(7)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 13

Pila di Attivazione

m

Blocchi di memoria per ogni chiamata

ðrecord di attivazione della chiamata

ðtutte le informazioni necessarie al processore per eseguire la chiamata

m

Record di attivazione (“Stack Frame”)

ðcontiene tutte lo spazio per i dati del modulo ðcontiene i riferimenti al codice del modulo ðcontiene i riferimenti per gestire le regole di

visibilità (vediamo una versione semplificata)

Record di Attivazione

m

Struttura

ðidentificatore del modulo (ad ogni modulo viene assegnato un codice numerico)

ðriferimento al codice (indirizzo di memoria del registro a cui comincia il codice del corpo) ðpunto di ritorno (indirizzo di memoria

dell’istruzione successiva da eseguire al termine della chiamata)

Sottoprogrammi: Concetti Avanzati >> Pila di Attivazione

(8)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 15

Record di Attivazione

m

Struttura (continua)

ðspazio per i parametri (registri destinati ai parametri del modulo)

ðspazio per costanti e variabili locali (registri destinati ai dati locali del modulo)

ð“puntatore di catena statica” (indirizzo del blocco di memoria contenente i dati globali)

16

Record di Attivazione

m

Esecuzione di una chiamata

ðcreazione del record di attivazione per la chiamata e passaggio dei parametri

ðassegnazione al “program counter” del riferimento al codice

ðesecuzione del codice del sottoprogramma ðal termine: assegnazione al “program

counter” del punto di ritorno ðrilascio del record di attivazione

Sottoprogrammi: Concetti Avanzati >> Pila di Attivazione

(9)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 17

Record di Attivazione

m

Regole di visibilità

ðogni volta che viene richiesto l’accesso ad un dato in un modulo, il processore cerca il dato tra i dati locali

ðse trova un dato con il nome richiesto, lo utilizza

ðaltrimenti segue il puntatore di catena statica per cercare un eventuale dato globale con lo stesso nome, ed usa quello

Record di Attivazione

m

Nel seguito

ðun esempio basato sull’applicazione della Morra Cinese

ðutilizza varie semplificazioni

ðper i riferimenti al codice utilizzeremo il codice sorgente invece che il codice macchina

ðinoltre, trascureremo i record di attivazione dei sottoprogrammi predefiniti

Sottoprogrammi: Concetti Avanzati >> Pila di Attivazione

(10)

G. Mecca - Programmazione Procedurale in Linguaggio C++... ... 19 }

#118

return;

#117 }

#106

cout << " Benvenuto, " << nome << "\n";

#116

getline(cin, nome);

#115

cout << "Immetti il tuo nome ";

#114

void schermoIniziale(string& nome) { // id=2

#113 }

#112

return;

#111

schermoIniziale(nome);

#110

srand(seme); //***

#109

int seme = time(NULL); //***

#108

void inizioGioco(string& nome) { // id=1

#107

schermoFinale(nome);

#105

gioca(nome);

#104

inizioGioco(nome);

#103

string nome;

#102

void main() { // id blocc=0

#101

const int MANI=3;

#100

...

...

...

#1000 p. cat. statica

#1016

#1004 nome

#1015

#111 punto rit.

#1014

#114 rif. codice

#1013

2 id blocco

#1012

#1000 p. cat. statica

#1011

xxx seme

#1010

#1004 nome

#1009

#104 punto. rit.

#1008

#108 rif. codice

#1007

1 id blocco

#1006

#1000 p. cat. statica

#1005

xxx nome

#1004

- punto rit.

#1003

#102 rif. codice

#1002

0 id blocco

#1001

3 MANI

#1000

Esempio: Equazioni di II Grado

20

Record di Attivazione

m

In concreto

ðla pila è fatta di registri di memoria ðpiù un indicatore di riempimento (“stack

pointer”)

ðpush: aumento dell’indicatore di riempimento e inizializzazione dei registri der record di att.

ðpop: diminuzione dell’indicatore di riempimento

Sottoprogrammi: Concetti Avanzati >> Pila di Attivazione

(11)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 21

Record di Attivazione

m

Attenzione

ðla memoria riservata alla pila di attivazione è tipicamente fissata dal compilatore

ðvalori tipici: da 64KB a 1MB ðpuò essere configurata

m

“Stack Overflow”

ðcondizione di errore irreversibile dovuta al tentativo di allocare memoria nello stack oltre il limite fissato

Funzionamento del Compilatore

m

Codice eseguibile di un’applicazione

ðcodice oggetto dell’applicazione (variabile da applicazione ad applicazione)

ðcodice oggetto per la gestione della pila (uguale in tutte le applicazioni)

ðquest’ultimo si incarica di creare e rilasciare i record di attivazione

ðe di gestire opportunamente l’esecuzione delle chiamate

Sottoprogrammi: Concetti Avanzati >> Funzionamento del Compilatore

(12)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 23

Funzionamento del Compilatore

m

Cosa sono il compilatore e il collegatore?

ðapplicazioni software

ðimplementano un algoritmo relativamente complesso ma comprensibile

m

Passo 1: analisi lessicale

ðraggruppamento dei caratteri del codice sorgente in gruppi detti “token”

ðparole chiave, identificatori, punteggiatura

24

Funzionamento del Compilatore

m

Passo 2: analisi sintattica

ðverifica che la sequenza dei token del programma rispetti le regole della grammatica

ðse non è così: errore sintattico

m

Passo 3: traduzione in codice oggetto

ðtraduzione di ciascuna istruzione nelle

corrispondenti istruzioni del linguaggio macchina

Sottoprogrammi: Concetti Avanzati >> Funzionamento del Compilatore

(13)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 25

Funzionamento del Compilatore

m

Passo 4: collegamento

m

Passo 5: aggiunta del codice per l’esecuzione

ðaggiunta del codice oggetto per il caricamento e l’avvio del programma

ðaggiunta del codice oggetto per la gestione delle operazioni sulla pila di attivazione

Una Domanda

m

Perché tutta questa complessità ?

ðnon sarebbe più semplice assegnare

staticamente la memoria a ciascun

sottoprogramma all’inizio dell’esecuzione ?

m

In questo caso si avrebbe una notevole semplificazione

ði moduli avrebbero blocchi di memoria fissati ðtutti i record di attivazione del modulo

sarebbero conservati nello stesso blocco

Sottoprogrammi: Concetti Avanzati >> Funzionamento del Compilatore

(14)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 27

La Ricorsione

m

La risposta: la “ricorsione”

ðquesta è la ragione alla base della pila di att.

m

Ricorsione

ðtecnica per cui un sottoprogramma può (direttamente o indirettamente) chiamare sé stesso

ðdi conseguenza, possono essere

contemporaneamente attive varie attivazioni dello stesso sottoprogramma

28

La Ricorsione

m

Perché la ricorsione è importante ?

ðmolti problemi matematici sono basati su

definizioni “ricorsive”

ðdefinizioni in cui il problema è definito in termini di (varianti di) sé stesso

m

In questi casi

ðla strategia di programmazione basata sull’uso della ricorsione nel programma è la più naturale

Sottoprogrammi: Concetti Avanzati >> La Ricorsione

(15)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 29

Un Esempio: Il Calcolo del Fattoriale

m

E’ possibile darne due definizioni

m

Definizione aperta (“iterativa”) – già vista

ð0! = 1, 1! = 1

ðn! = n x (n-1) x (n-2) x...x 2 x 1

m

Definizione ricorsiva

ð0! = 1 (caso base della def.)

ðn! = n x (n-1)! (caso ricorsivo della def.)

Soluzione Ricorsiva

const int massimo=13;

int fattoriale (int n) { int fatt;

if (n<0 || n>massimo) { return -1;

}

if (n==0) { fatt = 1;

} else {

fatt = n * fattoriale(n-1);

}

return fatt;

}

Sottoprogrammi: Concetti Avanzati >> La Ricorsione

Codice per il caso base Codice per il caso ricorsivo

(16)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 31

Un Esempio: Il Calcolo del Fattoriale

m

Esempio:

ðmain chiama fattoriale(3)

ðfattoriale(3) chiama fattoriale(2) ðfattoriale(2) chiama fattoriale(1) ðfattoriale(1) chiama fattoriale(0) ðfattoriale(0) restituisce 1

ðfattoriale(1) restituisce 1*1=1 ðfattoriale(2) restituisce 2*1=2 ðfattoriale(3) restituisce 3*2=6

32

Soluzione Ricorsiva

Sottoprogrammi: Concetti Avanzati >> La Ricorsione

Memoria RAM memoria per i

dati globali memoria per il main

memoria per fattoriale(3) memoria per

fattoriale(2) memoria per

fattoriale(1) memoria per

fattoriale(0)

(17)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 33

La Ricorsione

m

In realtà

ðla ricorsione è una tecnica di programmazione complessa

ðper ogni soluzione ricorsiva di un problema, ne esiste sempre una iterativa; esempio: il fattoriale

ðinoltre la ricorsione peggiora le prestazioni (altissima dinamica nella pila)

ðquindi, la ricorsione è spesso inutile

La Ricorsione

m

Però

ðci sono problemi che hanno una definizione ricorsiva più naturale di quella iterativa

ðesempio: algoritmi su alcune strutture di dati (liste, alberi e grafi)

ðin questi casi la programmazione ricorsiva è spesso più naturale di quella iterativa

ðsolo in questi casi è opportuno utilizzare la ricorsione

Sottoprogrammi: Concetti Avanzati >> La Ricorsione

(18)

G. Mecca - Programmazione Procedurale in Linguaggio C++ 35

Riassumendo

m

Pila di Attivazione

ðRecord di Attivazione

m

Funzionamento del Compilatore

m

La Ricorsione

36

Termini della Licenza

m This work is licensed under the Creative Commons Attribution- ShareAlike License. To view a copy of this license, visit

http://creativecommons.org/licenses/by-sa/1.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Termini della Licenza

m Questo lavoro viene concesso in uso secondo i termini della licenza “Attribution-ShareAlike” di Creative Commons. Per ottenere una copia della licenza, è possibile visitare

http://creativecommons.org/licenses/by-sa/1.0/ oppure inviare una lettera all’indirizzo Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Riferimenti

Documenti correlati

Tesi di Laurea - Progetto di un ponte in calcestruzzo armato precompresso costruito per conci.

Simbolo letto dall’ingresso (pu` o non leggere nulla) L’automa a pila passa alla configurazione successiva:. cambiando

Volta notò però che l'esperimento riusciva bene se l'archetto era formato da metalli diversi (per esempio zinco e rame) e ipotizzò il contrario, che la carica elettrica fosse

Con queste parole, Arthur Compton il 2 dicembre 1942 salut´ o il funzion- amento della pila atomica progettata da Enrico Fermi (primo reattore nu- cleare), con la quale, per la

4 Sezioni e viste impalcato rampa entrata - scala 1:50 Sezioni travi, traversi e pile rampa entrata - scala 1:50 Piante e sezioni fondazioni rampa entrata - scala 1:50 Piante, viste

2) Scalpellatura e rimozione zone cls ammalorato in fase di rigonfiamento o distacco ove necessario, pulizia delle superfici per eliminare residui di polvere, bonifica delle

&#34;ARENA S.ANTONIO&#34; E DELLE RAMPE DELLO SVINCOLO &#34;VOMERO&#34;.

[r]