Zum Inhalt springen

Maschinensprache i8086/ Speicher

Aus Wikibooks

Theorie:  EinleitungMaschinenspracheAssemblerZahlensystemeRAM-AdressenBWSDebugCPU-RegisterEinfache BefehleStringbefehleInterruptsI/O-Ports
Versuch:  BWS1BWS2Hallo WeltBootsektorMBR
Nützlich: BefehlslistePAUSEFilter
Analyse:  Bootloader


Die Speicheradressierung im Real-Modus

[Bearbeiten]

Die folgende Beschreibung bezieht sich auf die Speicheradressierung der Intel Prozessoren i8086 und i8088, entwickelt im Jahr 1978. Aus Kompatibilitätsgründen verhält sich bis heute jeder in einem PC verwendete Prozessor, auch wenn er von AMD, Cyrix oder Via ist, im Real Modus wie eine i8086 CPU.

Speicherplätze im Hauptspeicher (RAM) werden mit Nummern (Adressen) bezeichnet, beginnend ab Null. Jedes Byte hat seine eigene Adresse. Ein i8086 hat eine 20 Bit Adresse, die höchste mögliche Adresse ist also 2 hoch 20 minus 1 = 1048575 ca. 1 MB.

Nun arbeitet das Rechenwerk der CPU aber nur mit 16 Bit, deshalb sind auch die Adressregister nur 16 Bit groß. Dadurch lassen sich also nur 64k Byte (2 hoch 16 = 65536 Byte) direkt adressieren. Um den gesamten Speicher nutzen zu können, hätte man wie bei früheren Computern den 1 MByte Adressraum in 16 sogenannte Speicherbänke oder Segmente zu je 64k teilen können. Durch manuelle oder programmgesteuerte Umschaltung, das sogenannte Bank Switching, hätte man der CPU jeweils einen Speicherbereich bereitstellen können.

Intel hat vier sogenannte „Segmentregister“ eingeführt, in denen je eine Segmentnummer gespeichert wird:

CS:  Code-Segment zeigt auf den Speicherbereich für Befehle. Das IP-Register (Instruction Pointer) enthält die Adresse des nächsten Befehls.
DS:  Daten-Segment  zeigt auf einen Datenbereich.
ES: Extra-Segment zeigt auf einen zweiten Datenbereich
SS: Stack-Segment zeigt auf den „Kellerspeicher-Bereich“

Jede Segmentnummer zeigt auf den Anfang eines 2 hoch 16 = 64k Byte großen Adressbereichs.

Der Befehlssatz der CPU enthält Befehle, um den Inhalt dieser Register zu lesen und zu ändern. Mit einem geeignetem Programm kann man durch blockweises Umschalten schrittweise nacheinander den gesamten RAM nutzen.

Der obere Teil der Speicheradresse (der sich in einem der Segmentregister befindet) heißt Segment-Adresse, die unteren 16 Bit der vollständigen RAM-Adresse nennt man Offset-Adresse. Mit diesem Konzept bleiben 12 Bit der Segmentadresse ungenutzt. Würde man von den Segmentregistern nicht nur vier Bit, sondern alle 16 Bit nutzen, kann man 2 hoch 16 Segmente zu je 64k Byte = 4 GByte RAM verwalten. Mit dieser schlichten, übersichtlichen Architektur brachte Motorola 1979 den Prozessor 68000 auf den Markt.

Intel hat sich aber etwas weit eleganteres einfallen lassen, was für die Effektivität der Speichernutzung vorteilhaft, aber für Menschen nicht leicht verständlich ist.

Der Speicher wird nicht in 16 Segmente zu 64k Byte, sondern in 64k Segmente zu je 16 Byte „zerlegt“. Dabei überlappen sich die oberen 12 Bit der Offsetadresse mit den unteren 12 Bit der Segmentadresse.

   Bit 19    16      12     9 8 7 6 5 4 3 2 1 0  der Adresse
       +-------------------------------+
       ¦1¦0¦1¦1¦1¦0¦0¦0¦0¦0¦0¦0¦0¦0¦0¦0¦	   Segment B800 hex
       +-------+-+-+-+-+-+-+-+-+-+-+-+-+-------+
               ¦0¦0¦0¦0¦0¦0¦0¦0¦1¦0¦1¦0¦0¦0¦0¦0¦  Offset   00A0 hex
               +-------------------------------+

Dadurch kann jede (durch 16 teilbare) Adresse des Speichers zu einer Segment-Anfangsadresse werden.

Wegen der Überlappung kann jede Speicheradresse durch viele Kombinationen von Segment- und Offsetadresse bezeichnet werden, z. B. hat der Beginn der zweiten Bildschirmzeile im Bildwiederholspeicher im Textmodus die Adresse B80A0, was man so schreiben kann:

    B800:00A0 oder B80A:0000 oder B809:0010 oder B000:80A0 oder ...
=   B800           B80A           B809           B000
   + 00A0         + 0000         + 0010         + 80A0
=   B80A0          B80A0          B80A0          B80A0