# Segmentazione (memoria)

La segmentazione, in ambito informatico, è una comune tecnica di gestione della memoria che suddivide la memoria fisica disponibile in blocchi di lunghezza fissa o variabile detti segmenti. Uno dei possibili fini di tale tecnica è l'implementazione di meccanismi di protezione della memoria. Un'altra tecnica comune che assicura la protezione fra processi diversi è il paging. In un sistema operativo che usa la segmentazione, un indirizzo di memoria contiene una parte che identifica un segmento, e una parte che specifica l'offset entro il segmento indicato. La segmentazione è applicata di solito direttamente allo spazio di indirizzamento fisico o ad uno spazio di indirizzamento virtuale derivato da quello fisico con un'applicazione lineare.
Oltre all'indirizzo fisico ed alla lunghezza, ad un segmento può essere associata una combinazione di permessi in base ai quali si determina a quali processi è consentito o negato un certo tipo di accesso. In questo modo ad esempio è possibile distinguere segmenti di programma, di dati e di stack. Il gestore della memoria può così fare in modo che da un segmento di programma vengano caricate solo istruzioni (e non, ad esempio, dati) o che le informazioni caricate da un segmento di dati non vengano interpretate come istruzioni per il processore. Inoltre, un segmento può possedere un flag che specifica se il segmento stesso è presente nella memoria principale o se va recuperato da un supporto di memoria secondaria prima di essere utilizzabile. Se un processo cerca di accedere ad un segmento che non è attualmente disponibile nella memoria principale, si verifica un'eccezione hardware che permette al sistema operativo di caricare il segmento d'interesse dalla memoria secondaria.

## Supporto dell'hardware

I moderni processori dispongono di una speciale componente hardware integrata per la traduzione di indirizzi virtuali in indirizzi fisici, l'unità di gestione della memoria (Memory management unit, MMU) che adempie anche al compito di verificare la validità di un indirizzamento. Sui sistemi che non dispongono di un tale componente, come il processore Intel 80286, gli indirizzi fisici possono essere calcolati a partire dagli indirizzi virtuali solo per mezzo di una funzione lineare. Per questo tipo di processori la segmentazione è l'unico metodo di gestione della memoria in modalità protetta. Va notato tuttavia che la segmentazione utilizzata dai processori 80286 e successivi permette di proteggere la memoria assegnando permessi di lettura e scrittura; con i processori x86 precedenti, al contrario, una protezione di questo tipo non risultava possibile. Se è disponibile una MMU, come nel caso dei processori Intel 80386 o superiori, il sistema operativo può stabilire se utilizzare una tabella di paging o servirsi della comune tecnica di segmentazione per le normali operazioni di accesso alla memoria.

### La segmentazione

La tecnica della segmentazione presuppone una suddivisione logica, effettuata a priori, del programma che andrà in esecuzione. Tale suddivisione prevede l'individuazione di unità di dimensioni diverse, chiamate "segmenti", sulla base di criteri logici anche da parte del programmatore. Un programma può essere suddiviso in un segmento contenente il codice relativo alle procedure di uso più frequente, in un altro contenente le variabili globali e così via. La suddivisione in segmenti è dettata da criteri di minimizzazione delle chiamate tra segmenti. Per riferirci a un oggetto all'interno del programma occorrerà conoscere il "numero di segmento" in cui è contenuto e l'indirizzo all'interno del segmento, detto offset.
Quindi l'indirizzo logico di un oggetto sarà:
Indirizzo logico di X = (NumSegmento, Offset)
Per calcolare l'indirizzo fisico di un oggetto occorrerà conoscere l'indirizzo di memoria centrale dal quale inizia il segmento fisico relativo al segmento logico e aggiungere l'offset. A ogni segmento logico corrisponde un segmento fisico allocato in "celle contigue" di memoria centrale. Per la traduzione dell'indirizzo logico in indirizzo fisico si utilizza una tabella detta tabella di traduzione dei segmenti, che contiene, per ogni processo, le seguenti informazioni riguardanti i segmenti logici corrispondenti a quel processo:
* L'indirizzo di memoria centrale di inizio del segmento fisico;
* La dimensione del segmento.
Lo spazio fisico della memoria può essere gestito con la tecnica della partizioni variabili; in questo modo, quando un processo chiede l'allocazione di un segmento, il sistema operativo cerca di assegnargli una partizione libera seguendo una delle politiche di allocazione già viste: best fit, first fit o worst fit.
Generalmente, occorre quindi gestire lo spazio libero aggiungendo alla tabella precedente anche le entrate relative ai "segmenti" liberi. Lo spazio libero subirà periodici ricompattamenti.
La segmentazione appare una generalizzazione della tecnica di allocazione a partizioni variabili, in cui si consente al programmatore di suddividere il programma in segmenti ognuno dei quali allocato in una partizione.
Questa suddivisione facilita il reperimento di partizioni rispetto al caso di un unico grande segmento per tutto il programma.

### Memoria virtuale segmentata

La memoria virtuale segmentata consiste nell'usare congiuntamente la suddivisione in segmenti e nel caricare in memoria solo i segmenti che occorrono. Per far questo occorre conservare (così come avveniva per le pagine logiche nella paginazione) nella tabella di traduzione dei segmenti anche le seguenti informazioni:
* un bit che indica se il segmento logico è caricato o meno in memoria centrale;
* l'indirizzo di memoria centrale di inizio del segmento fisico;
* la dimensione del segmento;
* un bit che indica se il segmento è stato modificato in memoria centrale;
* la posizione sul disco del segmento logico.
Quando un segmento non è presente in memoria si solleva un'interruzione di segment fault che viene trattata in modo analogo al page fault, ecc.

### Vantaggi e svantaggi della segmentazione

Rispetto alla paginazione, la segmentazione ha il vantaggio di suddividere il programma in moduli logicamente coesi; in questo modo si riducono i tempi di I/O da disco.
Inoltre le "strutture dati" per la tabella di traduzione devono risiedere anch'esse in memoria centrale occupando spazio prezioso.
La segmentazione produce "frammentazione esterna", dovuta alla diversa dimensione dei segmenti così come accadeva per l'organizzazione a partizioni variabili. Anche per la segmentazione occorrono quindi attività periodiche di compattamento e riallocazione dei segmenti in uso.