Aree di Memoria e lo Stack
La RAM (Random Access Memory) è una delle principali aree di memoria del computer, utilizzata per l'elaborazione dei dati e delle istruzioni da parte del processore. La RAM funziona come un' area di lavoro temporanea per il computer, dove i dati vengono caricati e scaricati rapidamente. Tuttavia, la RAM è una memoria volatile, il che significa che i dati vengono persi quando il computer viene spento.
La RAM (Random Access Memory) è divisa in diverse aree di memoria, ognuna delle quali ha una specifica funzione. Le principali aree di memoria della RAM includono:
Area del codice: contiene il codice eseguibile del pgm.
Area dati globali: contiene
le variabili globali e
statiche (static) e costanti.
Area stack: contiene i record di attivazione delle funzioni (parametri e variabili locali).
Area heap: disponibile per allocazioni dinamiche.
Code Segment
Il Segmento codice è un'area di memoria riservata al codice del programma. Qui vengono memorizzate le istruzioni del programma e il codice eseguibile. Questa area di memoria è anche conosciuta come sezione di testo, poichè contiene solo dati di sola lettura e non è possibile modificarli durante l'esecuzione del programma.
Il segmento codice viene allocato durante la fase di compilazione del programma e la sua dimensione dipende dal numero di istruzioni del programma e dalla complessità del codice sorgente.
Il sistema operativo si occupa di proteggere il segmento codice dalla scrittura, in modo che il programma possa essere eseguito senza rischi di modifiche accidentali o dannose. Inoltre, il sistema operativo mantiene la coerenza del codice in memoria, garantendo che le istruzioni del programma siano eseguite nell'ordine corretto.
Inoltre, il segmento codice è importante per le prestazioni del sistema, poichè le istruzioni del programma vengono eseguite direttamente dalla CPU. La presenza di un segmento codice ben ottimizzato può quindi migliorare le prestazioni del sistema e ridurre i tempi di esecuzione del programma.
Data Segment
Il Segmento dati è un'area di memoria riservata ai dati statici e alle variabili globali. In pratica, quando un programma viene caricato in memoria, le variabili globali e i dati statici vengono memorizzati nel segmento dati.
Il segmento dati può contenere diverse tipologie di dati, come ad esempio:
- Variabili globali: variabili che possono essere accedute da qualsiasi parte del programma.
- Costanti: valori che non possono essere modificati durante l'esecuzione del programma.
- Variabili statiche: variabili che mantengono il loro valore tra le diverse chiamate di una funzione.
- Dati inizializzati: dati che vengono assegnati un valore in fase di compilazione.
Il segmento dati viene allocato durante la fase di caricamento del programma in memoria e la sua dimensione dipende dalla quantità di dati statici e variabili globali che vengono definiti nel codice sorgente.
La gestione del segmento dati viene eseguita dal sistema operativo, che assegna la memoria necessaria per le variabili globali e i dati statici durante l'esecuzione del programma. Inoltre, il sistema operativo si occupa anche di garantire la protezione dei dati nel segmento dati, per evitare che un programma possa accedere ai dati di un altro programma.
Stack
Lo Stack è un'area di memoria riservata alla gestione delle chiamate di funzione e delle variabili locali. In pratica, quando una funzione viene chiamata, i suoi parametri e le sue variabili vengono memorizzati nello stack.
Il funzionamento dello stack è basato sulla struttura LIFO (Last In First Out), ovvero l'ultimo oggetto inserito nello stack è il primo a essere rimosso. Lo stack è organizzato in modo sequenziale, ovvero gli oggetti vengono allocati in modo ordinato sulla memoria.
Lo stack viene utilizzato per memorizzare: le variabili locali e i parametri delle funzioni, nonchè per mantenere traccia delle chiamate di funzione.
- Le variabili locali
- I parametri delle funzioni
- Mantenere traccia delle chiamate di funzione
Quando una funzione viene chiamata, il suo spazio di memoria viene allocato nello stack e quando la funzione termina, lo spazio di memoria viene rilasciato.
L'area stack contiene i record di attivazione delle funzioni. Un record di attivazione rappresenta l'ambiente della funzione e contiene:
- I parametri ricevuti
- Le variabili locali
- L'indirizzo (del chiamante) a cui tornare alla fine
- Un riferimento al record di attivazione del chiamante
Ad ogni attivazione di funzione viene creato un nuovo record di attivazione specifico per quella chiamata.
La dimensione del record di attivazione varia da una funzione all'altra ma, per una data funzione, è fissa e
calcolabile a priori
Il record di attivazione viene creato automaticamente nel momento in cui la funzione viene chiamata.
Rimane sullo stack per tutto il tempo in cui la funzione è in esecuzione.
Viene deallocato automaticamente quando la funzione termina
Quando la funzione termina, il controllo torna al chiamante, che deve riprendere la sua esecuzione
dall'istruzione successiva alla chiamata della funzione.
A questo scopo, quando il chiamante chiama la funzione, si inseriscono nel record di attivazione della funzione anche:
- L'indirizzo di ritorno (return address), ossia l'indirizzo della prossima istruzione del chiamante che andrà eseguita quando la funzione terminerà
- Il link dinamico (dynamic link), ossia un collegamento al record di attivazione del chiamante, in modo da poter ripristinare l'ambiente del chiamante quando la funzione terminerà
Evoluzione dello stack:
Qui sotto si può vedere l'evoluzione dello stack all'interno della funzione cubo():
Regola di esistenza delle variabili locali: Le variabili dell'ambiente locale vengono create (allocate) automaticamente all'atto della chiamata e vengono distrutte (deallocate) automaticamente all'atto del ritorno al chiamante.
Heap
L'Heap è un'area di memoria dinamica che viene utilizzata per l'allocazione di memoria durante l'esecuzione di un programma. Quando un programma richiede l'allocazione di memoria dinamica, il sistema operativo assegna un blocco di memoria nello heap.