Frage

Ich lese über Speicheradressierung. Ich habe gelesen Segment versetzt und dann über Deskriptor Offset. Ich weiß, wie die genaue Adressen im real-Modus zu berechnen. Das alles ist in Ordnung, aber ich bin nicht in der Lage zu verstehen, was genau ist versetzt? Überall lese ich:

  

Im realen Modus sind die Register nur 16 Bits, so können Sie nur Adresse   bis zu 64k. Um zu ermöglichen, von mehr Speicheradressierung, Adresse ?? ist   berechnet aus dem Segment * 16 + Offset.

Hier kann ich die erste Zeile verstehen. Wir haben 16 Bits, so dass wir auf 2 ^ 16 = 64k adressieren kann.

Aber was ist diese zweite Linie? Was das Segment darstellen? Warum wir es mit 16 multiplizieren? warum wir hinzufügen versetzt. Ich kann einfach nicht verstehen, was das ist versetzt? Kann mir jemand mir das erklären oder geben bitte Link?

War es hilfreich?

Lösung

Unter x86 Real-Modus-Speicher der physikalische Adresse ist 20 Bit lang und wird calcolated:

PhysicalAddress = Segment * 16 + Offset

Überprüfen Sie auch: Real-Modus-Speicherverwaltung

Andere Tipps

Wenn Intel wurde die 8086 Gebäude, war es ein gültiges Argument für mit mehr als 64 KB in einer Maschine, aber es gab keine Möglichkeit, es jemals einen 32-Bit-Adressraum verwenden würde. Damals war sogar ein Megabyte eine ganze Menge Speicher. (Denken Sie daran, das berüchtigte Zitat „640K sollte für jeden genug sein?“ Es ist im Wesentlichen eine falsche Übersetzung der Tatsache, dass damals, 1MB flippte großen .) Das Wort „Gigabyte“ nicht gemeinsam sein würde, Verwendung für weitere 15-20 Jahre, und es wäre nicht wie weitere 5-10 Jahre RAM mit Bezug auf danach.

Anstatt also einen Adressraum so groß umzusetzen, dass es würde „nie“ voll ausgenutzt werden, was sie taten, war 20-Bit-Adressen implementieren. Sie benutzten noch 16-Bit-Worte für Adressen, denn schließlich ist dies ein Prozessor 16-Bit ist. Das obere Wort war das „Segment“ und das untere Wort der „Offset“ wurde. Die beiden Teile überlappen beträchtlich, obwohl - ein „Segment“ ist ein 64KB Teil des Speichers, die beginnt, bei (segment) * 16 und der „Offset“ irgendwo innerhalb dieses chunk verweisen. Um die tatsächliche Adresse zu berechnen, Sie multiplizieren das Segment Teil der Adresse, die von 16 (oder verschiebt es um 4 Bits nach links ... gleiche), und fügen Sie dann den Offset. Wenn Sie fertig sind, haben Sie eine 20-Bit-Adresse.

 19           4  0
  +--+--+--+--+
  |  segment  |
  +--+--+--+--+--+
     |   offset  |
     +--+--+--+--+

Zum Beispiel, wenn das Segment 0x8000 war, und der Offset war 0x0100, die tatsächliche Adresse kommt zu ((0x8000 << 4) + 0x0100) == 0x80100.

   8  0  0  0
      0  1  0  0
  ---------------
   8  0  1  0  0

Die Mathematik ist selten, dass ordentlich, obwohl - 0x80100 kann buchstäblich Tausende von anderem Segment dargestellt werden:. Offset-Kombinationen (4096, wenn meine Mathe ist rechts)

Ich möchte hier eine Antwort hinzuzufügen, nur weil ich habe das Internet wurde zum Scheuern versucht, dies zu verstehen. Die anderen Antworten verließen eine wichtige Information, dass ich über den Link in einer der Antworten vorgestellt hast. Allerdings habe ich fast verpasst es total. Beim Durchlesen der gelinkten Seite, war ich immer noch nicht verstehen, wie dies funktioniert.

Das Problem, das ich wahrscheinlich hatte war von mir nur wirklich verstehen, wie der Commodore 64 (6502-Prozessor) Speicher angelegt. Es verwendet ähnliche Schreibweise Adressenspeicher. Es hat 64k des gesamten Speicher und verwendet 8-Bit-Werte von PAGE: OFFSET Zugriffsspeicher. Jede Seite ist 256 Bytes lang (8-Bit-Zahl) und die Offsetpunkte einem der Werte in dieser Seite. Die Seiten sind Rücken an Rücken im Speicher beabstandet. So Seite 2 beginnt dort, wo Seite 1 endet. Ich wollte in die 386 die gleiche Art zu denken. Das ist nicht so.

Realmodus wird mit einem ähnlichen Stil, auch wenn es andere Formulierung SEGMENT ist: OFFSET. Ein Segment ist 64 KB groß. Allerdings sind die Segmente selbst nicht angelegt Rücken an Rücken wie der Commodore war. Sie sind voneinander beabstandet sind 16 Bytes. Offset arbeitet immer noch das gleiche, die angibt, wie viele Bytes von der Seite \ Segmentanfang.

Ich hoffe, diese Erklärung hilft jemand, der diese Frage findet, mich in schriftlicher Form geholfen hat.

Ich kann die Frage und Antworten sind einige Jahre alt, aber es ist eine falsche Aussage, dass es nur 16-Bit-Register bestehen im Real-Modus.

Im Realmodus werden die Register sind nicht nur 16 Bit, denn es gibt auch 8-Bit-Register zu. Jeder dieser 8-Bit-Register ist ein Teil eines 16-Bit-Register, das in einen unteren und einen oberen Teil eines 16-Bit-Register unterteilt sind.

Und Starten den Real-Modus mit einem 80386+ wir werden 32-Bit-Register und zusätzlich auch zwei neue Anweisung Präfixe, ein für außer Kraft zu setzen / Rückwärts die Standardoperanden-Größe und ein für außer Kraft setzen / Rückwärts die Standardadresse-Größe eines Anweisung innerhalb eines Codesegment.

können diese Anweisung Präfixe in Kombination verwendet werden, um die Operanden-Größe umzukehren und die Adress-Größe zusammen für einen Befehl. Im real-Modus der Standard-Operanden-Größe und adress Größe beträgt 16 Bit. Mit diesen beide Anweisungs Präfixen können wir einen 32-Bit-Operanden verwenden / registrieren Beispiel für einen 32-Bit-Wert in einem 32-Bit-Registern berechnen oder für einen 32-Bit-Wert zu und von einer memmory Position zu verschieben. Und wir können alle 32-Bit-Register (möglicherweise in Kombination mit einer Basis + Index * scale + Verschiebung) verwendet wird als ein Adresse-Register, aber die Summe der effektiven Adresse nicht über die Grenze der 64 kb-Segment-Größe überschreiten sein .

(Auf der OSDEV-Wiki-Seite können wir in der Tabelle finden für die „Operand-Größe und Adresse-size Überschreibung Präfix“, dass der „0x66 Operanden-Präfix“ und „0x67 Adresse Präfix“ N / A (nicht aviable ) für den Real-Modus und den virtuellen 8086-Modus. http://wiki.osdev.org/X86-64_Instruction_Encoding
Aber diese totaly falsch ist, weil in dem Intel-Handbuch können wir diese Aussage finden.)

„können Diese Präfixe sowie im geschützten Modus und virtuellen 8086-Modus in Echt Adresse Modus verwendet werden“

Beginnend mit einem Pentium MMX wir werden acht 64-Bit-MMX-Register.
Beginnend mit einem Pentium 3 werden wir acht 128-Bit XMM-Register.
..

Wenn ich nicht falsch bin, dann ist die 256-Bit-YMM-Register und die 512-Bit-ZMM-Register und die 64-Bit-Allzweckregister eines x64 nicht innerhalb des Real-Modus verwendet werden.

Dirk

Minimal Beispiel

Mit:

  • offset = msg
  • Segment = ds
mov $0, %ax
mov %ax, %ds
mov %ds:msg, %al
/* %al contains 1 */

mov $1, %ax
mov %ax, %ds
mov %ds:msg, %al
/* %al contains 2: 1 * 16 bytes forward. */

msg:
.byte 1
.fill 15
.byte 2

Also, wenn Sie den Zugriff auf Speicher wollen über 64k:

mov $0xF000, %ax
mov %ax, %ds

Beachten Sie, dass dies für Adressen größer als 20 Bit ermöglicht breit, wenn Sie so etwas wie verwenden:

0x10 * 0xFFFF + 0xFFFF == 0x10FFEF

Bei älteren Prozessoren, die nur 20 Adressleitungen hatte, wurde sie einfach abgeschnitten, aber später auf die Dinge habe mit der A20-Leitung (21 Adresse Draht) kompliziert: https://en.wikipedia.org/wiki/A20_line

Auf einem GitHub Repo mit der erforderlich vorformulierten um es auszuführen.

Ein 16-Bit-Register kann nur auf 0xFFFF adressieren (65.536 Bytes, 64 KB). Wenn das nicht genug war, Intel hinzugefügt Segmentregister.

Jedes logisches Design einfach kombiniert zwei 16-Bit-Register hätte einen 32-Bit-Adressraum zu machen, (zB 0xFFFF : 0xFFFF = 0xFFFFFFFF), aber nooooo ... Intel mußten alles auf uns seltsam erhalten.

Historisch gesehen, der Frontside-Bus (FSB) hatte nur 20 Adressleitungen und damit nur 20-Bit-Adressen übertragen könnte. Um "korrigieren" diese, entwickelte Intel ein System, in dem Segmentregister nur Ihre Adresse durch 4 Bits erweitern (16bits + 4 = 20, in der Theorie).

Um dies zu erreichen, wird das Segmentregister wird nach links verschoben, von seinem ursprünglichen Wert von 4 Bits, dann an die Adresse in Ihrem allgemeinen Register hinzugefügt (z. [es:ax] = ( es << 4 ) + ax) . . Hinweis: Left 4 Bits Verschiebung entspricht von 16 bis Multiplikation

Das ist es. Hier einige anschauliche Beispiele:

;; everything's hexadecimal

[ 0:1 ] = 1

[ F:1 ] = F1

[ F:0 ] = F0

[ F:FF] = 1EF ; [F becomes F0, + FF = 1EF]

[ F000 : FFFF ] = FFFFF (max 20-bit number)

[ FFFF : FFFF ] = 10FFEF (oh shit, 21-bit number!)

So können Sie immer noch mehr als 20-Bit-Adresse. Was geschieht? Die Adresse „umschlingt“, wie Modul-Arithmetik (als natürliche Folge der Hardware). So 0x10FFEF wird 0xFFEF.

Und dort haben Sie es! Intel stellte einige dumme Ingenieure, und wir müssen damit leben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top