Newsgroup: it.comp.lang.c
Titolo: Gestione della memoria

Non sono mai riuscito a capire bene quello che riguarda la gestione della
memoria, soprattuto le differenze tra 16 e 32 bit e i modelli di memoria.
Piu' o meno so che con 16 bit si possono allocare solo 64k di memoria. E fin
qui totto a posto. Il fatto e' che non ho capito se sia la limitazione della
grandezza di un array o la dimensione di una variabile (per esempio
utilizzando variabili long).
Inoltre e' una limitazione di un solo array per volta oppure globale (per
esempio due matrici da 32k l'una dovrebbero essere il massimo)?
Pero' utilizzando i modelli di memoria (es. Huge) si può utilizzare 1MB(di
cui 640K utilizzabili e 256 riservati giusto?). E per utilizzare l'altra
memoria? Per utilizzare la memoria estesa? E quella espansa (che adesso
credo che non si utilizzi piu')?
Scusate il numero delle domande, ma su questo argomento ne so veramente
poco. Se poteste chiarirmi le idee ve ne sarei grato.
Va bene anche qualche sito che ne parli in modo chiaro, visto che nei
manuali di C e' spiegato molto superficialmente (almeno in quelli che ho
letto io :-)).

 Piu' o meno so che con 16 bit si possono allocare solo 64k di memoria.
Atteniamoci allo standard. Per esso i modelli di memoria non esistono.
Le dimensioni dei tipi (con certi vincoli) sono le uniche grandezze
dipendenti dalla macchina (almeno per l'argomento di cui parliamo). La
memoria allocabile dipende dalla dimensione del tipo size_t che può
appunto variare da compilatore a compilatore e da sistema a sistema.
EMG

credo che non si utilizzi piu')?
Si accede in modo lineare per mezzo delle funzioni in modalita'
protetta controllate dal processore.

 [snip]
La gestione della memoria dipende direttamente dalla CPU del sistema in
questione (8, 16 o 32 bit) e dalla modalità in cui questa lavora (reale,
protetta, virtuale, ecc.). Per capire bene l'argomento (che è abbastanza
ostico) è necessario partire da lontano.
Nelle CPU 8088 e 8086 si lavorava, rispettivamente, a 8 e 16 bit di dati con
un bus degli indirizzi a 20 bit. L'indirizzamento avveniva in modalità
reale, utilizzando 16 bit di offset e 16 di segmento. Quest'ultimo veniva
"shiftato" a sinistra di 4 bit e, sommandolo al valore del registro di
offset (IP, DI, ecc), si otteneva un valore a 20 bit rappresentante
l'indirizzo fisico del dato da prelevare.
Es.  CS=0100011001110011   IP=1000011011110110
Indirizzo=  (spero l'allineamento del testo venga mantenuto)
0100011001110011 +
         1000011011110110
-------------------------------------
01001110111000100110
Questo tipo di indirizzamento aveva due limitazioni: il limite del Mb (come
hai fatto notare tu) e la segmentazione: non si poteva avere un dato (che
fosse un array, una struttura o cos'altro) maggiore di 64kb (il limite
indirizzabile da un singolo segmento). Era tuttavia possibile utilizzare
(con gli appropriati modelli di memoria) fino a 640kb. Questo è il tipo di
indirizzamento usato fino ad oggi dall'MS-DOS.
Con il 286 si è arrivati a 24 bit di indirizzo ed è stato quindi possibile
raggiungere il limite dei 16Mb, anche se nessun SO (tranne OS/2) ha
sfruttato questa peculiarità. E' stata introdotta la modalità di
indirizzamento virtuale, in cui il segmento non veniva più sommato
all'offset, bensì era l'indice di una tabella chiamata "tabella dei
descrittori di segmento" (segment descriptor table). Ogni entry di questa
tabella, formata da 8 byte (l'entry), conteneva l'indirizzo di base del
segmento, i suoi limiti e alcuni bit di controllo.
Il 386 con i suoi 32 bit ha segnato una rivoluzione nell'indirizzamento di
memoria. Riuscendo a puntare 4Gb ha permesso l'abbandono dei segmenti (però
ancora presenti per l'indirizzamento virtuale fino a 64 TeraByte). Sono
state pienamente supportate la modalità protetta (presente anche nel 286) e
la gestione delle pagine di memoria da 4kb ciascuna.
Oggi come oggi con Windows si utilizza la modalità protetta e la gestione
avanzata delle pagine di memoria dei processori Pentium et similia. Win32 ha
un suo modo per puntare ai dati (che non spiego in questo post per brevità
ma che potrei illustrare in un altro momento).
Mi scuso per la lunghezza del post e anche per gli errori che per la fretta
non ho potuto correggere
Giuseppe