Simon S. schrieb:
> Ich gehe richtig davon aus, dass die Adresse des "Hello World!" auf den
> Anfang des Adressbereiches dieses Prozesses bezogen ist, oder?
Es ist eine virtuelle Adresse. Ihr Gültigkeitsbereich ist nur
der Prozess selbst, in dem du sie siehst. Wenn du das Programm
ein zweites Mal parallel startest, sieht das Programm die gleiche
Adresse, obwohl es im Speicher durchaus unterschiedliche Adressen
sein könnten.
Auf welche physische Adresse sie abgebildet wird, ist dabei völlig
offen. Wenn das Programm startet, wird sie gar nicht abgebildet.
Sowie das erste Mal auf die Speicherseite zugegriffen wird, in der
diese Adresse liegt, gibt es einen page fault, der zu einem so
genannten trap ins Betriebssystem führt. Das System analysiert
daraufhin, ob der Zugriff ein gültiger war oder nicht. Wenn nicht,
bekommt das Programm ein Signal (SIGBUS oder SIGSEGV), welches
normalerweise zur sofortigen Beendigung des Programmes führt.
War der Zugriff gültig, dann gibt es im Grunde zwei Möglichkeiten:
1.) Der zugehörige Speicherbereich bildet auf einen Block auf dem
Sekundärspeicher (Festplatte) ab; es wird eine freie physische
Speicherseite gesucht (ggf. muss eine andere dafür freigeschaufelt
werden) und diese mit der virtuellen Adresse verbunden; danach
wird der Seiteninhalt vom Sekundärspeicher nachgeladen, und das
Programm fortgesetzt.
2.) Der zugehörige Speicherbereich ist "anonym", d. h. nicht durch
Sekundärspeicher abgedeckt; es muss auch eine freie physische
Speicherseite gefunden und verbunden werden; diese wird
anschließend aus Sicherheitsgründen (kein Zugriff auf Daten
fremder Applikationen oder Nutzer!) ausgenullt, und das
Programm fortgesetzt.
Fall 2 betrifft den Stack oder nicht explizit initialisierte Daten
(.bss-Bereich). Fall 1 betrifft einerseits Programmcode oder
konstante Daten. Wenn physischer Speicher knapp wird, müssen diese
Bereiche nicht auf Sekundärspeicher zurückgeschrieben werden, da sie
ja jederzeit von diesem wieder erneut gelesen werden können. Fall 1
kann aber auch initialisierte Daten betreffen, diese werden anfangs
aus dem Programmabbild selbst geladen. Wenn physischer Speicher knapp
wird und diese Seiten ausgelagert werden müssen (oder auch Seiten, die
ursprünglich über Fall 2 angelegt worden sind), dann wir deren Inhalt
in den Swap-Bereich ausgelagert. Von da geht es dann später über Fall
1 weiter, aber diesmal wird nicht aus dem Programmabbild nachgeladen,
sondern aus dem Swap-Bereich.
Ist ein wenig vereinfacht dargestellt ;-), aber ungefähr so arbeiten
alle VM-Systeme (virtual memory), beginnend mit dem legendären VMS von
DEC, die dieses Prinzip mit den Vax-Computern seinerzeit eingeführt
haben.
> Warum ist die Adresse 0x40066c? (entspricht ziemlich genau 4MegaByte)
Den Teil "warum 4 MiB" hat dir A. K. beantwortet.
Der Teil "warum nicht genau 4 MiB" hängt damit zusammen, dass die
gesamte ELF-Datei selbst auf eine "glatte" Adresse abgebildet wird,
einschließlich all ihrer Headerdaten. Damit ergeben sich dann für
die tatsächlichen Adressen im Programm (Startadresse, Beginn des
Datenbereichs etc.) "unrunde" Adressen.