Ich untersuche das Speicherlayout eines bestimmten Prozesses. Ich stelle fest, dass der Startspeicherplatz für jeden Prozess nicht 0 ist. Auf dieser website beginnt TEXT bei 0x08048000. Ein Grund kann sein, die Adresse mit dem NULL-Zeiger zu unterscheiden. Ich frage mich nur, ob es noch einen anderen guten Grund gibt? Vielen Dank.Speicher Startort in C
Antwort
A loader Lasten in einem binären Segmenten in dem Speicher: Text (Konstanten), Daten-Code. Es ist nicht notwendig, von 0 zu starten, und wie C ist das Problem von Bugs rund um Null, wie in a[i]
, die sogar gefährlich ist. Dies erlaubt (auf einigen Prozessoren), Segmentierungsfehler abzufangen.
Es wäre die C-Laufzeit, die einen linearen Adressraum von 0 einführt. Das wäre vorstellbar, wenn C die Implementierungssprache des Betriebssystems ist. Aber dient keinem Zweck; Der Heapspeicher beginnt bei 0. Das Speichermodell ist eines der Segmente. Ein Code-Segment ist möglicherweise vor Änderungen durch einige Prozessoren geschützt.
Und in Segmenten Zuweisung geschieht in C Runtime verwaltete Speicherblöcke.
Ich könnte hinzufügen, dass physische 0 und höher oft vom Betriebssystem selbst verwendet wird.
Ich denke, das bringt es auf:
Jeder Prozess seinen eigenen Satz von Seitentabellen hat, aber es gibt einen Haken. Sobald virtuelle Adressen aktiviert sind, gelten sie für alle Software, die auf der Maschine ausgeführt wird, einschließlich des Kernels selbst. Daher muss ein Teil des virtuellen Adressraums für den Kernel reserviert sein.
Also während der Prozess seinen eigenen Adressraum bekommt. Ohne dem Kernel einen Block zuzuordnen, wäre es nicht in der Lage, Kernel-Code und Daten zu adressieren.
Dies ist immer der erste Speicherblock, der angezeigt wird, und enthält daher die Adresse 0. Der Benutzermodusbereich beginnt darüber hinaus, und daher befinden sich sowohl der Stapel als auch der Heapspeicher dort.
von NULL
Zeiger Erkennungsmerkmal
Selbst wenn der Benutzer-Modus Raum an der Adresse gestartet 0
, gäbe es keine Daten an die Adresse zugewiesen sein 0
wie in dem Stapel sein wird oder der Haufen, die sich nicht Beginnen Sie am Anfang des Benutzerbereichs. Daher könnte NULL
(mit dem Wert 0
) noch verwendet werden und ist kein Grund für dieses Layout.
Ein Vorteil im Zusammenhang mit der NULL
und der erste Block als Kernel-Speicher ist jeder Versuch, NULL zu lesen/zu schreiben, löst einen Segmentierungsfehler aus.
Dennoch, was genau liegt in der '0 .. 0x08048000' Bereich? –
Der Null-Zeiger muss nicht wirklich 0 sein. Im C-Standard ist garantiert, dass ein 0-Wert im Kontext eines Zeigers vom Compiler als NULL
behandelt wird.
Aber die 0, die Sie in Ihrem Quellcode verwenden, ist nur syntaktischen Zucker, die keine Beziehung zu der tatsächlichen physischen Adresse der Null-Zeiger-Wert hat "zeigt" auf.siehe
Für weitere Informationen:
- Why is NULL/0 an illegal memory location for an object?
- Why is address zero used for the null pointer?
Eine Anwendung auf Ihrem Betriebssystem hat seinen einzigartigen Adressraum, der es als ein kontinuierlicher Speicherblock sieht (die Speicher ist nicht physisch kontinuierlich, es ist nur "der Eindruck", den das Betriebssystem jedem Programm gibt.
Für den größten Teil, jeden virtuelle Speicherraum des Prozesses wird auf ähnliche und vorhersehbare Weise angelegt (dies ist das Speicherlayout in einem Linux-Prozess, ein 32-Bit-Modus):
(Bild von Anatomy of a Program in Memory)
Sehen Sie sich das Textsegment an (die Standardtextbasis auf x86 ist 0x08048000, die vom Standardlinkerskript für die statische Bindung ausgewählt wurde).
Warum die magische 0x08048000? Wahrscheinlich weil Linux diese Adresse vom System V i386 ABI ausgeliehen hat.
... und warum hat dann System V 0x08048000 verwendet?
Der Wert wurde ausgewählt, um den Stapel unter dem .text-Abschnitt aufzunehmen, , der nach unten wächst. Die 0x48000 Bytes könnten durch die gleiche Seite Tabelle zugeordnet werden, die bereits vom Abschnitt .text benötigt wird (wodurch in den meisten Fällen eine Seitentabelle gespeichert wird), während die verbleibenden 0x08000000 mehr Raum für stapelhungrige Anwendungen zulassen würden.
Gibt es etwas unter 0x08048000? Es könnte nichts sein (es ist nur 128M), aber you can pretty much map anything you desire there, using the mmap() system call. auch
Siehe:
- 1. Fenster Startort aus Ressourcenwörterbuch
- 2. So teilen Startort zu Zielroute
- 3. Speicher modifiziert in C++
- 4. Zuordnung "unmanaged" Speicher in C#
- 5. C++ stream in den Speicher
- 6. Union Speicher teilen in C
- 7. Über dynamischen Speicher in C++
- 8. Speicher QML Bild in C++
- 9. wie ich Speicher in C
- 10. Speicher Funktionen in Arrays C++
- 11. Bereinigt C# C++ reservierten Speicher?
- 12. C# Threading Speicher Ausnahme
- 13. C# Speicher von Informationen
- 14. C++ - Makros mit Speicher?
- 15. C++/Qt-Speicher Leck?
- 16. Scan-Speicher (C++)
- 17. C++ Multithreading - Speicher Synchronisation
- 18. Grund C++ Speicher Frage
- 19. C++ - Speicher Tabelle
- 20. C++ - Ausrichten Speicher
- 21. C++ Speicher HoughLinesP
- 22. von C++ nach C# // Struktur Speicher Optimierung
- 23. Speicher-Layout Kompatibilität zwischen C und C++
- 24. Gibt es binäre Speicher Streams in C++
- 25. Drucken Bytes aus dem Speicher in C
- 26. Zeige Speicher und CPU in C
- 27. Problem mit großem Speicher in C#
- 28. Wie Speicher für meine Datenstruktur in C
- 29. Explizit Speicher in C# zu befreien
- 30. Speicher mit C++ in Echtzeit vormerken
Warum ist 0x00400000 der Standard-Basisadresse für eine ausführbare Datei? http://blogs.msdn.com/b/oldnewthing/archive/2014/10/03/10562176.aspx – auselen