Speichersegmentierung in 8086

Wenn der externe Speicher (1 MB) in einem 8086-basierten System in Code, Daten, Stack und Extras unterteilt ist, die alle 64 kB groß sind, was machen wir dann mit dem Rest des Speichers? Wird es verschwendet?

Verwenden Sie verschiedene Segmente und ändern Sie sie nach Bedarf. Willkommen in den 1980er Jahren!
Weckt Erinnerungen (Wortspiel beabsichtigt) ;)
Übrigens ist es kein externer Speicher; das wäre das 5¼", das Winchester usw. RAM ist intern. Vielleicht verwechseln Sie es mit erweitertem Speicher.

Antworten (3)

Beim 8086 hat jedes Segment ja 64 KiB. Diese Segmente können sich jedoch bewegen.

Sie setzen einen "Segmentzeiger", der definiert, wo ein Segment beginnt. Er fungiert als Adress-Offset, der zur internen 16-Bit-Adresse des Programmzählers (oder eines anderen Indizierungsregisters) addiert wird.

Das Ändern der Segmentzeiger ist eine triviale Angelegenheit. Obwohl Sie also nur auf 64 KiB gleichzeitig zugreifen können, können Sie dieses 64-KiB-Fenster nach Belieben verschieben, um auf die gesamten 1 MiB Speicherplatz zuzugreifen.

Beachten Sie auch, dass sich diese Segment-Offsets alle 16 Bytes überlappten, da der 8086 ein 20-Bit-Adressierungsschema hatte.

Wenn Sie beispielsweise einen CS bei 0x0010 und einen SS bei 0x0011 hatten, [CS]:[0x0010] = [SS]:[0x0000]

siehe: http://en.wikipedia.org/wiki/Intel_8086#Segmentation

Die Anzahl der Segmente bestimmt den Platz im Speicher. Segment 0 beginnt an der physikalischen 0-Adresse des Speichers. Segment 1 beginnt bei 0x10 Bytes von vorne, Segment 2 bei 0x20 usw.

Ja, Segmente beginnen jeweils mit 0x10 Bytes, sind aber 64k lang, was bedeutet, dass sie sich stark überlappen.

Es gibt Segmentregister: CS (Codesegment), DS (Datensegment), SS (Stapelsegment) und ES (Extrasegment). Byte-Grained-Adressen werden mit Pointer-Registern erhalten: IP (Instruction Pointer), SP (Stack Pointer) und BP (Base Pointer).

Die aktuell ausgeführte Anweisung befindet sich bei CS:IP (Segmentnummer von CS + IP-Bytes-Offset).

Wenn Sie mit Daten arbeiten, ohne das Segment explizit anzugeben, ist DS die Voreinstellung (zumindest in der Notation von Turbo Assembler). Zum Beispiel:

mov cx, [bp]

ist das gleiche wie:

mov cx, ds:[bp]

Ich bin mir über die genaue Syntax nicht sicher (es ist ungefähr 15 Jahre her, seit ich sie verwendet habe).

Sie können einem Segmentregister nicht direkt einen Wert zuweisen. Sie müssen dies über allgemeine Register tun, z.

mov ax, 100h
mov ds, ax

Um also ein Wort von der physikalischen Adresse 0x105 in BX zu laden, können Sie dies folgendermaßen tun:

xor ax, ax  ; equal to mov ax, 0 but faster
mov ds, ax
mov ax, 105h
mov bx, [ax]

oder durch Verwendung eines anderen Segments:

mov ax, 10h
mov ds, ax
mov ax, 5
mov bx, [ax]
Speicheradressen, die einen [BP]-Offset enthalten, verwenden eher das SS-Register als das DS; Tatsächlich denke ich, dass Segmentpräfixe bei Anweisungen ignoriert werden, die diese Adressierungsmodi auf dem 8088 verwenden, sodass sie immer SS verwenden, selbst wenn ein anderes Segmentpräfix angegeben ist.
Sie haben Recht mit BP - das Standardsegmentregister dafür ist SS. DS bleibt jedoch der Standard für AX, BX, CX, DX und natürlich für SI, was ich vergessen habe zu erwähnen. Es gibt auch DI, das ES zugewiesen ist, wenn ich mich gut erinnere (zumindest in den Anweisungen von movsb / movsw).
Beim 8086 gibt es 24 Adressierungsmodi der Form base+disp+ofs, wobei base nichts, BX oder BP ist; disp ist nichts, SI oder DI, und ofs ist 0, 1 oder 2 Bytes. Drei Drei-Wege-Wahlmöglichkeiten würden 27 Möglichkeiten ermöglichen, aber der Modus [nichts+nichts+ofs] erfordert einen 2-Byte-Offset, und [BP+nichts+ofs] erfordert einen 1- oder 2-Byte-Offset. Die Befehle STOSB, STOSW, MOVSB ​​und MOBSW werden in ES:DI gespeichert; Dies sind die einzigen Anweisungen, die standardmäßig ES verwenden (und sie können kein anderes Segment verwenden).
Es ist nicht irgendeine Assembler-Notation, die dsvoreingestellt ist – es ist die Art und Weise, wie der Befehlssatz funktioniert. Wenn Sie nämlich Segment überschreiben, generiert der Assembler das entsprechende Segment-Überschreibungspräfix, andernfalls generiert er Anweisungen ohne Präfix, und dies macht effektiv den dsStandardwert (für Anweisungen, die diesem Prinzip gehorchen).
Außerdem axist Ihre Verwendung von fehlerhaft. Es gibt keinen solchen Adressierungsmodus wie [ax]. Sie können entweder [eax]beginnend mit i386 verwenden oder sind auf [bx+si], [bx+di], [bp+si], [bp+di], [si], [di], [bp], beschränkt [bx].