2014-10-09 15 views
7

Sto esaminando il layout di memoria di un determinato processo. Ho notato che la posizione di memoria iniziale di ogni processo non è 0. Su questo website, TEXT inizia da 0x08048000. Un motivo può essere quello di distinguere l'indirizzo con il puntatore NULL. Mi sto solo chiedendo se ci sono altri buoni motivi? Grazie.posizione iniziale di memoria in C

+0

Perché 0x00400000 l'indirizzo di base di default per un file eseguibile? http://blogs.msdn.com/b/oldnewthing/archive/2014/10/03/10562176.aspx – auselen

risposta

0

Un loader carichi un binario in segmenti nella memoria: testo (costanti), dati di codice. Non è necessario iniziare da 0, e poiché C ha il problema degli errori di accesso intorno a null, come in a[i] che è addirittura pericoloso. Ciò consente (su alcuni processori) di intercettare i guasti di segmentazione.

Sarebbe il runtime C che introduce uno spazio di indirizzo lineare da 0. Potrebbe essere immaginabile dove C è il linguaggio di implementazione del sistema operativo. Ma non ha scopo; per fare in modo che l'heap inizi da 0. Il modello di memoria è uno dei segmenti. Un segmento di codice potrebbe essere protetto dalle modifiche da parte di alcuni processori.

E nell'allocazione dei segmenti avviene nei blocchi di memoria gestita in esecuzione C.

È possibile aggiungere che lo 0 fisico e l'alto sono spesso utilizzati dal sistema operativo stesso.

2

penso che questo lo riassume:

Ogni processo ha una propria serie di tabelle di pagina, ma c'è un inghippo. Una volta abilitati gli indirizzi virtuali, si applicano a tutto il software in esecuzione nella macchina, incluso il kernel stesso. Quindi una parte dello spazio di indirizzamento virtuale deve essere riservata al kernel.

Così mentre il processo ottiene il proprio spazio di indirizzamento. Senza allocare un blocco al kernel, non sarebbe in grado di indirizzare il codice e i dati del kernel.

Questo è sempre il primo blocco di memoria che appare e quindi include l'indirizzo 0. Lo spazio della modalità utente inizia oltre questo, ed è così che risiedono sia lo stack che l'heap.

Distinguendo da NULL puntatore

Anche se lo spazio in modalità utente ha iniziato all'indirizzo 0, non ci sarebbe alcuna dati allocati all'indirizzo 0 come che essere nella pila o mucchio che si no iniziare all'inizio dell'area utente. Pertanto, NULL (con il valore di 0) potrebbe essere utilizzato ancora e non è un motivo per questo layout.

Tuttavia, un vantaggio relativo allo NULL e il primo blocco alla memoria del kernel è qualsiasi tentativo di leggere/scrivere su NULL genera un errore di segmentazione.

+0

Ancora, cosa si trova esattamente nella gamma '0 .. 0x08048000'? –

3

Il puntatore nullo non deve in realtà essere 0. È garantito nello standard C che quando un valore 0 viene assegnato nel contesto di un puntatore viene considerato come NULL dal compilatore.

Ma lo 0 che si utilizza nel codice sorgente è solo zucchero sintattico che non ha alcuna relazione con l'indirizzo fisico effettivo al quale il valore del puntatore nullo è "puntato".

Per ulteriori dettagli si veda:

Un'applicazione sul tuo sistema operativo ha il suo spazio di indirizzamento unico, che vede come un blocco continuo di memoria (memoria non è fisicamente continuo, è solo "l'impressione" che il sistema operativo dà ad ogni programma).

Per la maggior parte, lo spazio di memoria virtuale di ogni processo è definito in maniera simile e prevedibile (questo è il layout di memoria in un processo Linux, modalità a 32 bit):

Memory layout in a Linux process (immagine da Anatomy of a Program in Memory)

Osservare il segmento di testo (la base di testo predefinita su x86 è 0x08048000, scelta dallo script linker predefinito per il collegamento statico).

Perché il magico 0x08048000? Probabilmente perché Linux ha preso in prestito quell'indirizzo dall'ABI System i386.

... e perché il sistema V ha utilizzato 0x08048000?

Il valore è stato scelto per contenere lo stack sotto la sezione .text, crescente verso il basso. I byte 0x48000 potrebbero essere mappati dalla stessa tabella già richiesta dalla sezione .text (salvando quindi una tabella di pagina nella maggior parte dei casi), mentre il rimanente 0x08000000 consentirebbe più spazio per applicazioni affamate di stack.

C'è qualcosa sotto 0x08048000? Non potrebbe esserci nulla (è solo 128M), ma you can pretty much map anything you desire there, using the mmap() system call.

Consulta anche:

Problemi correlati