Eine Frage zu Segmente
-
also ich bin ein blütiger Anfänger in der Programmiersprache Assembly, hab ein paar tut durchgelesen, naja, gab mal schon schwierigkeit, die ich nicht verstehen konnte, aber diesmal, verstehe ich die Aufteilung des Arbeitspeicher in sogenannte Segments nicht so richtig.
so weit ich verstanden hab, wird der 1MB (1048576bytes) grosse Arbeitspeicher durch 16 geteilt, daraus ergibt 65536 (65536 bytes oda?) also sind das 16 x 65536 bytes, und jeder dieser 16 aufgeteilten Bereich hat eine maximale Größe von 64KB. soweit richtig oda?
hier ein Textausschnitt aus den tut, den ich gefunden hab:
"An welchen Adressen beginnen nun Segmente? Dividieren wir die maximale Größe des Adressraumes durch die maximal mögliche Anzahl an Segmenten, so erhalten wir 2^20 / 2^16 = 2^4 = 16. Ein Segment ist also ein Block mit einer Größe von 16 Bytes. Ein Segment kann demzufolge an jeder Adresse beginnen, die ohne Rest durch 16 teilbar ist. In das Segmentregister muß dann die Nummer des Segmentes eingetragen werden. Dessen Adresse errechnet sich dann so:
Segmentnummer * 16 Bytes"wo kommt denn jetzt die 16 bytes her??
2^20 / 2^16 = 2^4 = 16 doch nicht etwa von dieser zahl, die steht doch dafür, dass es bei 1MB grosse RAM maximal 16 segmente gibt..
-
Die Segmente überlappen quasi.
Ein Segment ist 64K groß.
ABER du kannst über das Segmentregister in 16K "Auflösung" (Schrittweite) die Segmente wählen.
Also das Segmentregister immer um 4 Schritte erhöhen und du hast ein Segment komplett übersprungen.
-
wozu segmente überlappen? was bring das?
und "die Auflösung" in 16 KB, meinst du das in ein Segment wird, der 64KB gross wird in je 16KB aufgelöst?
-
Hi.
Das ganze "Geheimnis" liegt in der Formel, nach der sich eine physikalische Adresse im RealMode berechnet:
16 * Segment + Offset = Phys. Adresse
Folglich zeigen zB. folgende Beispieladressen (typische Segment:Offset-Form) alle auf die selbe Stelle im Speicher:
0040h:0100h (0040h * 10h + 0100h = 00500h)
und 0000h:0500h (0000h * 10h + 0500h = 00500h)
oder auch 0020h:0300h (0020h * 10h + 0300h = 00500h)usw...
Ist doch eigentlich gar nicht so schwer.[edit]
JnZn558 schrieb:
wozu segmente überlappen? was bring das?
Frag' den Designer des x86... Der hat sich das nunmal so ausgedacht.
JnZn558 schrieb:
und "die Auflösung" in 16 KB, meinst du das in ein Segment wird, der 64KB gross wird in je 16KB aufgelöst?
Ich glaube er meinte nicht 16K, sondern 16B(yte).
In den FAQ gibt's uebrigens zum Thema x86 und Abarten der Adressierung einen Link zu einer hervorragenden Seite auf Deutsch:
C/C++ Forum :: FAQ - Assembler :: Protected Mode / MMX :: http://www.fh-zwickau.de/doc/prmo/start.htm :: http://www.fh-zwickau.de/doc/prmo/pmtutor/text/index.htm
[/edit]
-
Die überlappenden Segmente sind durchaus notwendig: EXE-Files werden ja so gelinkt, dass alle FAR-Adressen einen fixen Offset-Anteil haben und nur der Segmentanteil über die relocations verändert wird. Hätte man jetzt nur das erste Segment bei 0000h, das zweite bei 1000h usw., dann könnte das Programm immer nur an diesen Stellen angesiedelt werden. Oder noch schlimmer, je nach Anfangsadresse von einem Speicher- oder Codeblock könnte man immer nur eine begrenzte Anzahl von Adressen darüber ansprechen. Wenn man sich die Segmente nicht als überlappende Blöcke vorstellt, sondern als abgetrennte Blöcke mit einer Startadresse und einer Länge, finde ich das ganz gut verständlich. So werden sie ja auch tatsächlich verwendet, nur gibt's halt keinen Hardwaremechanismus, um die Länge eines Segments anzugeben, somit sind alle Segmente automatisch 64KB lang und ragen über das logische Ende hinaus.
Ähnliche Mechanismen gibt's auch bei RISC-Maschinen, wo man mit manchen Befehlen nur Adressen erreichen kann, die "in der Nähe" sind - ist also vergleichbar mit "im gleichen Segment".