Die Speicheradressierung des 8086/8088
Für die Programmierung in Assembler ist die Art und Weise, wie der Prozessor den
Arbeitsspeicher verwaltet, von grundlegender Bedeutung, denn der Entwickler ist
in der Regel für den Zugriff auf den Arbeitsspeicher selbst verantwortlich. Es ist
daher wichtig zu wissen, nach welchem Prinzip der 8086-Prozessoren den Speicher
adressieren und welche Bedeutung dies für den Aufbau eines Assemblerprogramms hat.
Der 8086-Prozessoren verfügt über 20 Adressleitungen, die über den Adressbus mit dem
Arbeitsspeicher verbunden sind. Mit 20 Adreßleitungen lassen sich insgesamt 220
(1048576 Byte) (1 MByte) adressieren. Allerdings verfügt der 8086 nur über Register mit
einer Breite von 16 Bit. Würde zur Adressberechnung lediglich ein Register zagrunde gelegt,
ließe sich nur ein Arbeitsspeicher von 216 gleich 65536 Byte adressieren. Um
dennoch die gesammte Kapazität nutzen zu können, geht man folgenden Weg:
Jede Adresse wird stets aus zwei Komponenten zusammengesetzt, einem Segmentanteil
und einem sogenannten Offset, beide 16 Bit breit. Der Segmentanteil befindet sich in einem
der vier Segmentregister CS, DS, ES oder SS, während es sich bei dem Offset beispielsweise
um eine 16-Bit-Konstante oder um den Inhalt eines Registers handeln kann.
Immer, wenn eine Speicheiadresse zu bilden ist, multipliziert der Prozessor zunächst den
Segmentanteil mit 16. Dies ergibt ein Ergebnis mit 20 binären Stellen. Die Multiplikation
einer Dualzahl mit zwei entspricht bekanntlich dem Verschieben der gesamten Zahl um eine
Stelle nach links. Die neu entstehende Ziffer am rechten Ende wird mit einer Null aufgefüllt.
Eine Multiplikation mit 16 kommt daher einem viermaligen Verschieben nach links gleich.
Als nächstes wird der 16-Bit-Offset zu dem Ergebnis der Multiplikation addiert, woraus die
endgültige 20-Bit-Adtesse resultiert (physikalische Adresse). Diese kennzeichnet nun genau
eine Speicherzelle des Arbeitsspeichers. Diese spezielle Art der Adressberechnung hat direkte
und indirekte Einflüsse. Durch diese Adressierung wird der gesamte Arbeitsspeicherbereichin
Untereinheiten, Segmente aufteilt. Die Startadresse eines Segments wird stets durch den Inhalt
eines der vier Segmentregister festgelegt. Jedes Byte innerhalb dieses Segments wird über den
Offset adressiert. Der Offset ist ein 16-Bit-Wert, somit ist die Größe eines Segments auf 65536
Byte begrenzt. Ein Segment darf nur bei einer Adresse beginnen, die ohne Rest durch 16 teilbar
ist (Paragraphenadresse). Die Darstellungsweise einer Adresse wird allgemein im Format
Segment:0ffset angegeben. So bedeutet B000:0012hex, dass die Adresse aus dem Segmentanteil
B000hex und dem Offsetanteil 0012hex besteht. Somit lassen sich 65536 verschiedene Segmente
bilden.
|
Speicherzugriff |
Standardsegment |
Alternative |
Offset |
Befehl lesen |
CS |
keine |
IP |
Datenoperation |
DS |
CS, ES, SS |
EA |
Stapeloperation |
SS |
keine |
SP |
BP als Basis |
SS |
CS, DS, ES |
EA |
BX als Basis |
DS |
CS, ES, SS |
EA |
EA = effektive Adresse |
So setzt sich eine physikalische Adresse zusammen:
Segmentanteil * 16 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
B0720hex |
+ Offsetanteil |
|
|
|
|
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
00A2hex |
|
|
= phy. Adresse |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
B07C2hex |
|