Segmentierungsregister verwenden

Ich versuche zu verstehen, wie die Speicherverwaltung auf niedriger Ebene verläuft, und habe ein paar Fragen.

1) Ein Buch über Assemblersprache von Kip R. Irvine besagt, dass im Real-Modus die ersten drei Segmentregister mit Basisadressen von Code, Daten und Stapelsegment geladen werden, wenn das Programm startet. Das ist mir ein bisschen zweideutig. Werden diese Werte manuell angegeben oder generiert der Assembler Anweisungen zum Schreiben der Werte in Register? Wenn dies automatisch geschieht, wie wird die Größe dieser Segmente ermittelt?

2) Ich weiß, dass Linux ein flaches lineares Modell verwendet, d. H. Segmentierung in sehr begrenztem Umfang. Außerdem gibt es laut "Understanding the Linux Kernel" von Daniel P. Bovet und Marco Cesati vier Hauptsegmente: Benutzerdaten, Benutzercode, Kerneldaten und Kernelcode in GDT. Alle vier Segmente haben dieselbe Größe und Basisadresse. Ich verstehe nicht, warum es in vier von ihnen einen Bedarf gibt, wenn sie sich nur in Typ und Zugriffsrechten unterscheiden (sie produzieren alle die gleiche lineare Adresse, oder?). Warum nicht einfach einen von ihnen verwenden und seinen Deskriptor in alle Segmentregister schreiben?

3) Wie teilen Betriebssysteme, die keine Segmentierung verwenden, Programme in logische Segmente auf? Zum Beispiel, wie sie den Stack von Code ohne Segment-Deskriptoren unterscheiden. Ich habe gelesen, dass Paging verwendet werden kann, um mit solchen Dingen umzugehen, verstehe aber nicht, wie.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage