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
risposta
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.
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.
Ancora, cosa si trova esattamente nella gamma '0 .. 0x08048000'? –
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:
- Why is NULL/0 an illegal memory location for an object?
- Why is address zero used for the null pointer?
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):
(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:
- 1. Posizione memoria del valore enum in C
- 2. Posizione memoria arbitraria con dereference in C
- 3. Posizione iniziale del divisore NSSplitView
- 4. Aggiornamento MediaPlayer Posizione iniziale in pausa
- 5. È cross-browser 'iniziale' posizione - css
- 6. CABasicAnimazione - Impostazione della posizione del tratto iniziale
- 7. Variabile JavaScript posizione memoria
- 8. Indirizzo della memoria del blocco iniziale
- 9. Evitare iniziale memoria heap Errore formato
- 10. spostamento della posizione iniziale del modello di tela
- 11. Confronto di memoria (con posizione differenza)
- 12. Come memorizzare una variabile in una posizione di memoria specifica?
- 13. In che modo l'operatore di cancellazione C++ trova la posizione di memoria di un oggetto polimorfico?
- 14. C++ valore iniziale dell'array dinamico
- 15. C++: allocatori di memoria
- 16. C'è un modo per cambiare la posizione iniziale predefinita dell'emulatore?
- 17. Come modificare la posizione dell'immagine della schermata iniziale?
- 18. Posizione del mouse in C#
- 19. Gestione file di memoria mappato in C# direttamente dalla memoria
- 20. Un assunto di valore iniziale sulla mappa in C++
- 21. Qt: come impostare la posizione iniziale della finestra principale?
- 22. Come dereferenziare una posizione di memoria da ctypes python?
- 23. motivo di perdita di memoria in C C++
- 24. Profilo di allocazione della memoria in C++
- 25. Problema di memoria FlowDocument in C#
- 26. C++ quale libreria di compressione in memoria?
- 27. byte di stampa dalla memoria in C
- 28. Indirizzo memoria di accesso in C#
- 29. segmentazione per mancanza di memoria in C
- 30. C# Memorizza la memoria in%
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