|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
puntatori NEAR e FAR: perché non esistono più?
è da un po' che rifletto su questa cosa: sugli odierni processori di tipo Intel a 32 bit, qualsiasi puntatore da 32 bit è NEAR: un puntatore FAR infatti richiede 48 bit.
in Visual C++ (e credo anche in qualsiasi altro compilatore C/C++) l'asterisco, che serve a dichiarare puntatori, definisce sempre un tipo a 32 bit: sizeof(void*) infatti è uguale a 32, come anche sizeof(char*), sizeof(int*) e sizeof(<tipo_qualsiasi>*); ma i puntatori FAR che fine hanno fatto?? ![]() immaginiamo di avere un bel programma che viene distribuito su 4 segmenti: codice, dati, heap e stack (situazione tipica); se ho un puntatore ad un byte che sta nel segmento dati posso riferirmi a quel byte con soli 32 bit, e lo stesso se si trova nell'heap, ma come fa il compilatore a sapere il segmento a cui voglio riferirmi (heap o dati) quando la situazione non lo rende implicito? ![]() e un'altra cosa: è risaputo che l'indirizzo 0x00000000, cioè NULL, non è accessibile: ma perché mai questa cosa??? si tratta semplicemente di un puntatore che punta al base address di qualche segmento, a seconda che io in un puntatore FAR (appunto) specifichi il segmento dati, codice, heap o stack, ma il punto è che di qualunque segmento si tratti, se il segmento sta nel mio programma in teoria io dovrei avere lecito accesso al suo byte numero 0, o sbaglio?!? quello che in realtà può provocare il seg.fault è quando io specifico o un segmento inesistente, o un segmento di un altro programma, no? cos'è che mi manca di sapere e che mi impedisce di capire? ![]() |
![]() |
![]() |
![]() |
#2 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
ehm, un imperdonabile leggerezza: tutti quei sizeof naturalmente è sottinteso che non restituiscono 32, ma 4
![]() |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11782
|
Quote:
![]() I puntatori che dichiari non sono indirizzi di memoria fisici, ma sono indirizzo logici nello spazio di indirizzamento di un processo che poi la CPU mappa verso indirizzi fisici in base a determinate look up table che variano ovviamente da processo a processo. Si possono fare giochini tipo mappare piu' indirizzi logici allo stesso indirizzo fisico, mappando ad esempio le pagine di piu' processi che contengono il codice del processo stesso vero le stesse pagine fisiche dove il SO mantiene una sola copia del codice da condividere. E' un sistema piu' semplice ed efficacie della vecchia memoria segmentata il cui supporto e' mentenuto per motivi di compatibilita'.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#4 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
guarda che oggi segmentazione e paginazione esistono entrambe e la segmentazione sulla IA32 in modalità protetta a 32 bit non la si può eludere...
EDIT: mi sa che ti confondi con una roba che abbiamo studiato ad architettura 2 che non so cosa sia e che si chiama "partizionamento" (ho chiesto alla prof. se x caso c'entrava qualcosa con la segmentazione e ha detto di no). |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11782
|
Quote:
I registri di segmento vengono semplicemente impostati a descrittori di segmento che puntano all'inizio dello spazio di indirizzamento (semplifico, non e' proprio cosi' in WinXP) e la memoria gestita mediante paginazione. Non mi confondo col partizionamento ![]()
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#6 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
scusa, ma allora perché i registri di segmento normalmente contengono valori diversi?
![]() perché usare segmenti diversi che puntano tutti allo stesso base address? |
![]() |
![]() |
![]() |
#7 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
mi rispondo da solo: perché i vari segmenti hanno caratteristiche diverse nel descrittore
![]() ora ho capito, grazie dell'aiuto ![]() |
![]() |
![]() |
![]() |
#8 | ||
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11782
|
Quote:
Qui ci sono tutte le spiegazioni del caso: http://msdn.microsoft.com/msdnmag/issues/0700/hood/ E come ti dicevo la mia spiegazione era volutamente semplicistica, qui ti dice dove e quando Win32 fa chiamate a segmenti diversi: Quote:
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
||
![]() |
![]() |
![]() |
#9 | |||
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
Quote:
![]() Quote:
![]() Quote:
![]() ciao |
|||
![]() |
![]() |
![]() |
#10 | |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
Quote:
![]() il mio problema è che ho ancora le idee un tantino confuse perché su queste cose sono fresco di studi... ![]() mi propongo di migliorare ![]() cmq adesso mi sembra finalmente tutto chiaro (... sarà vero? ![]() |
|
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11782
|
Quote:
![]() Una cosa comoda che faccio per scovare i buffer overrun e di mettere in sola lettura pagine di dati che so di dover scrivere una volta sola, ad esempio le animazione che carico da disco, oppure la geometria dei modelli. Se qualcosa va in buffer overrun e prova a scrivere sulle mie pagine dati, parte un GP fault, molto meglio che sovrascrivere casualmente lo spazio d'indirizzamento del processo e causare bug che poi si rivelano sempre il giorno prima di una milestone.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#12 | ||
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
Quote:
![]() te l'avevo detto di risparmiarmi!! ![]() scherzo, su! ![]() Quote:
![]() |
||
![]() |
![]() |
![]() |
#13 | |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Jul 2004
Messaggi: 1578
|
48 bit = 16 bit di selettore di un descrittore di segmento appartenente a GDT (global descriptor table ad indirizzo virtuale fisso presente in un registro accessibile solo con istruzioni privilegiate) o alla LDT del task corrente (local descriptor table con indirizzo virtuale in LDTR) + 32 bit di offset
Poi ci sarebbero gli altri 4 bit dei 36 che sono fissi per ogni task e (se non sbaglio ) invisibili al programmatore, gestiti solo dal s.o. Naturalmente tutto questo solo se il s.o. va in modalità protetta, altrimenti i 16 rappresentano l'indirizzo virtuale base e si usa l'indirizzamento classico e senza protezione. Poi vabe la paginazione, se attiva, ottiene dalle tabelle delle pagine oppure dai TLB il mapping tra indirizzi virtuali e fisici (se non è cambiato dal Pentium dovrebbe essere 32 bit = 20 bit più significativi identificano una pagina da 4KB, 12 bit l'offset, oppure 10 bit identificano una pagina da 4MB, 22 l'offset). |
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: Jul 2004
Messaggi: 1578
|
Quote:
Non dimenticare che i descrittori di segmento li può creare solo il sistema operativo dato che le tabelle si trovano su segmenti a cui in generale accede solo lui. |
|
![]() |
![]() |
![]() |
#16 | ||
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11782
|
Quote:
![]() Ma ho il brutto vizio di leggere un post e rispondere, puoi mi accorgo che ti eri gia' risposto. Quote:
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
||
![]() |
![]() |
![]() |
#17 | |||
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
Quote:
Quote:
Quote:
![]() |
|||
![]() |
![]() |
![]() |
#18 | |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
Quote:
|
|
![]() |
![]() |
![]() |
#19 | ||
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7027
|
Quote:
![]() Quote:
Ultima modifica di 71104 : 06-07-2005 alle 12:09. |
||
![]() |
![]() |
![]() |
#20 | ||
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11782
|
Quote:
![]() Quote:
Immagina che debba caricare 20 mb di animazioni, alloco 20 mb di pagine, le imposto a scrittura/lettura, carico le animazioni da disco, le cambio in sola lettura. L'anno scorso avevo provato una cosa simpatica, ma alla fine non se n'era fatto nulla. L'idea era di prendere un blocco di dati a sola lettura ad esempio di 10 pagine, comprimerlo con un algoritmo non lossy ragionevolmente e memorizzarlo da qualche parte compresso. Poi chiedi al SO di darti 10 pagine di spazio di indirizzamento ma senza fare il commit a nessuna pagina fisica (cosi' non occupi memoria) e restituire il puntatore logico all'applicazione. Ora immagina che l'applicazione tenti di accedere al blocco di dati che lei vede non compresso e l'indirizzo si riferisca alla pagina 1. Win32 ti da' un'eccezione perche' quella pagina non e' mappata su nessuna pagina fisica, tu trappi l'eccezione, prendi quella pagina dalla versione compressa, la decomprimi al volo, fai il commit della pagina su una pagina fisica che usi come buffer di decompressione temporaneo e restituisci il controllo. Dopo il GP fault l'applicazione vede la pagina 1 decompressa e non sa quello che e' successo ![]() Funzionava benino ma la mia implementazione non era troppo robusta. Prova a farlo, e' un buon esercizio per imparare ad usare i servizi di Win32 per la paginazione.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
||
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:45.