Version 2.0 Aktualisiert: 30.03.04

Der 8086 Prozessor ist wie bereits erwähnt der Vorgänger heutiger Prozessoren wie der
80486´er (kurz 486´er) Prozessor sowie des Pentium bzw. Pentium II Prozessors. Der 8086´er
war der erste Prozessor, der 1 MB Speicher adressieren konnte, was damals noch recht viel war.
Prinzipiell gibt es nur wenig Unterschiede zwischen einem 8086 und z.B. einem 80486´er.
Der 486´er hat eine höhere Taktfrequenz (z.B 66 MHz statt 8 MHz) und benötigt pro Befehl
weniger Takte. Auch verfügt er über grössere Register (32 statt 16 Bit), einen breiteren
Daten und Adress-Bus und einen integrierten Coprozessor (zumindest der 486 DX)...
Hilfe ! Was zur Hölle ist ein Register oder was ist die Taktfrequenz und das andere Zeug
werden Sie jetzt vielleicht sagen. Nun genau das möchte ich hier kurz erläutern.
Zuerst werde ich erklären was ein Bit und was ein Byte ist. Der Computer kann eigentlich nur
zwischen zwei Zuständen unterscheiden, nämlich 1 und 0 d.h. soviel wie Strom oder nicht
Strom. Ein Bit stellt also die kleinste Speichereinheit dar. Aufgrund der Prozessorarchitektur
können jedoch Daten nicht in beliebiger Grösse verarbeitet werden. Da die internen
Verbindungswege (Bus) aus mindestens 8 Leitungen bestehen, haben die Entwickler von Intel
beschlossen, 8 Bits zu einer Einheit zusammenzufassen: Das Byte. Ein Byte ist also gleich 8
Bits.
Da ein Bit entweder 0 oder 1 speichern kann, also 2 Zustände annehmen kann, kann ein Byte
2 hoch 8 also 256 Zustände annehmen oder Zahlen von 0 bis 255 entsprechen. Das Bit das am
weitesten links steht, ist Bit Nummer 7. Es ist das sogen. höherwerigste Bit. Das Bit rechts
aussen ist Bit Nummer 0, ist das niederwertigste Bit. Es ergibt sich also folgende Abfolge:
höherwertigstes Bit --> 7 6 5 4 3 2 1 0 <-- niederwertigstes Bit.
Zwei Byte ergeben ein Wort (engl. Word). Dies teilt sich auf in zwei Byte - Teile:
Word: [ (15 14 13 12 11 10 9 8) (7 6 5 4 3 2 1 0) ]
höherwertiges Byte niederwertiges Byte
Analog dazu gibt es noch das Doppelwort (Doubleword=4Bytes), das Quadwort (Quadword=8Bytes)
und noch ein paar grössere, die aber nicht so wichtig sind.
Um grössere Speichersummen anzugeben verwendet man noch Kilobyte, Megabyte und Gigabyte:
1024 Byte sind ein Kilobyte (KB), 1024 Kilobyte sind ein Megabyte (MB) und 1024 Megabyte sind
ein Gigabyte.
Und nun zu Thema Taktfrequenz. Die Taktfrequenz wird meist in Megahertz (MHz) angegeben.
Ein Hertz ist eine Schwingung pro Sekunde, ein Megahertz entspricht folglich einer Million
Schwingungen pro Sekunde. Je höher die Taktfrequenz desto mehr Arbeitseinheiten in der Sekunde
kann der Prozessor verarbeiten und desto schneller ist der Informationsfluss und somit der
Computer. Jeder Maschinenbefehl braucht mindestens ein Takt meist jedoch mehr. Je moderner
der Prozessor desto weniger Takte werden pro Befehl benötigt. So benötigt z.B. der Befehl NOP,
das ist der Befehl, der im Prinzip nichts tut (No Operation), auf einem 8086´er noch 3 Takte,
auf einem 486´er benötigt er 1 Takt. Moderne Prozessoren (Pentium aufwärts) können
auch zwei Befehle gleichzeitig ausführen, jedoch sind nur bestimmte Kombinationen zugelassen.
Zum Schluss kommt das wichtigste: Die Register. Register sind Speicher, welche sich im Prozessor
befinden, und daher extrem schnell sind. Der Nachteil ist, dass sie klein sein müssen, um in den
Prozessor zu passen. Bis zum 286´er gibt es 16 Bit Register danach 32 Bit Register, welche
immer ein E vor dem Namen haben (z.B. EAX 32 Bit, AX 16 Bit). Für den Anfang werde ich jedoch
nur mit 16 Bit Registern arbeiten, der Einfachheit halber. Man kann die Register in vier
Kategorien unterteilen: Allzweckregister, Segmentregister, Zeige und Indexregister,
Flagregister.
1. Allzweckregister:
Die Allzweckregister haben eine Besonderheit: Sie lassen sich in zwei Teile unterteilen, einen
High- und einen Low-Teil von jeweils 8 Bit grösse. Im falle des schon genannten AX Registers
nennt man die beiden Teile AH und AL. Zu den Allzweckregistern zählen weiterhin BX, CX und DX.
Die Register lassen sich als ganzes oder getrennt in High- und Low-Teil bearbeiten.
Erklärung der einzelnen Allzweckregister:
a) Das AX Register:
Der Akkumulator (AX Register) wird bei arithmetischen Operationen eingesetzt. Es muss auch bei
der Multiplikation und Division verwendet werden.
b) Das BX Register:
Das Base (BX) Register wird bei Speicherzugriffen als Zeiger verwandt.
c) Das CX Register:
Das Count (CX) Register wird zum Beispiel in Schleifen eingesetzt. Beispiel: Eine Schleife mit
dem Befehl LOOP wird so lange wiederholt, bis CX = 0 ist.
d) Das DX Register:
Das Data (DX) Register dient zum Beispiel zur Aufnahme von Daten bei 16 Bit Multiplikationen
und Divisionen.
2. Segmentregister:
Bei den Segmentregistern handelt es sich um die Register CS (Codesegmentregister), DS
(Datensegmentregister), SS (Stacksegmentregister) und ES (Extrasegmentregister).
Diese Register werden dazu benötigt, die 1 MB Speicher im Real Mode anzusprechen. Mit den
CPU internen 16 Bit Registern kann man jedoch nur 65536 Byte ansprechen, um ein MB anzusprechen
wäre ein 20 Bit Register notwendig, das man damals aber aus technischen Gründen nicht bauen
konnte. Daher muss man einen Trick verwenden: Man unterteilt das eine MB in Segmente von
minimal 16 Byte. Mit einem 16 Bit Register kann man Adressen bis 65536 verwalten, da die
Segmente mindestens 16 Byte gross sind ergibt sich 65536 mal 16 = 1 Megabyte !
Die Segmentadresse gibt also ein Speicherabschnitt (Segment) innerhalb des 1 MB Adressraumes an.
Innerhalb dieser Segmente bewegt man sich mit Hilfe der Offsetadresse. Die Offsetadresse kann
wiederum nur maximal 65536 gross sein d.h. die maximale Segmentgrösse ist 65536 Byte (64 KB).
So lässt sich jede Adresse im physikalischen Speicher durch Angabe der Segment- und der
Offsetadresse eindeutig beschreiben. Der Prozessor kann aus diesem Adresspaar (man nennt das
Segment-Offset Adresspaar logische Adresse) die 20 Bit physikalische Adresse (also die
tatsächlichen Speicherstelle) berechnen.
Dies geschieht durch Multiplikation der Segmentadresse mit 10h (das h steht für Hexadezimal,
mehr dazu später 10h=16) und nachfolgender Addition der Offsetadresse.
Beispiel:
Gegeben sei die physikalische Adresse F2003h. Diese Adresse lässt sich logisch z.B. so
darstellen: F200h:0003h die Schreibweise ist also: Segmentadresse:Offsetadresse.
Rechnet man die logische Adresse noch obiger Regel um, so erhält man F2003h. Umgekehrt ist
dies allerdings nicht eindeutig möglich. Man kann allerdings zur Umrechnung einer physikalischen
Adresse in eine logische folgenden Trick anwenden: Man fasst die ersten 4 Ziffern zur
Segmentadresse zusammen und bildet aus der letzten Ziffer durch voranstellen dreier Nullen
die Offsetadresse.
3. Zeige und Index Register:
Hier gibt es die Register SI, DI, BP, SP, und IP. Sie lassen sich nur als 16 Bit Register
ansprechen.
a) Der Source Index (SI)
Wenn man z.B. einen String (Zeichenkette) verschieben möchte, so muss dieser Register
als Zeiger auf den Anfang des Strings dienen (in einem vorgegebenen Segment).
b) Der Destination Index (DI)
Im obigen Fall würde dieses Register das Ziel des zu kopierenden Strings beinhalten.
c) Der Basepointer (BP)
Er wird zum Beispiel verwendet um auf das Stacksegment zuzugreifen.
d) Der Stackpointer (SP)
Der Stackpointer zeigt stets auf die Aktuelle Position im Stacksegment. Der Stack (Stapel) bzw.
das Stacksegment wird zur Zwischenspeicherung von Werten benutzt. Zum Teil verwenden bestimmte
Prozessorbefehle den Stack (z.B. CALL), aber auch der Benutzer kann den Stack mittels der
Befehle push und pop verwenden. PUSH schiebt einen Wert auf den Stack POP holt ihn zurück.
Die Daten werden auf dem Stack nach dem Last in - First out (LIFO) Prinzip gespeichert.
Den Befehl, den Sie als letzten gesichert (gepusht) haben, bekommen sie beim poppen als erster
wieder heraus. Beispiel: Ich will die Register ax und bx auf dem Stack speichern, und danach
beide Register, die vielleicht inzwischen verändert wurden, wieder korrekt herstellen.
Dazu wird folgender Code verwendet:
push ax ;speichern von ax
push bx ;speichern von bx
. ;Die Punkte stehen für irgendwelche Befehle
. ;Mit einen ; werden Anmerkungen gekennzeichnet !
.
pop bx ;letztgespeicherter Wert in bx
pop ax ;erstgespeicherter Wert in ax
Später werde ich noch einmal auf den Stack eingehen !
e) Der Instruction Pointer (IP)
Der Instructoin Pointer zeigt immer auf die momentane Position im Codesegment. Man kann ihn
nicht direkt verändern, die Verwaltung übernimmt der Prozessor.
4. Das Flagregister
Das Flagregister ist 16 Bit breit. Es ist als ein Statusregister zu verstehen, und in einzelne
Flags unterteilt. Ein Flag kann also entweder gesetzt sein (also = 1) oder nicht (also = 0).
Es gibt folgende Flags:
Das Carry-Flag CF (es wird bei einem Überlauf gesetzt oder bei Fehlern), das Auxillary
Flag, das Overflow-Flag, das Sign Flag (es wird für Vorzeichenzahlen genutzt), das Parity
Flag, das Direction Flag, das Interrupt Flag, das Trap Flag und das Zero Flag ZF (Das Zero Flag
zeigt nach einer Operation an, ob das Ergebnis null ist oder nicht).
Manche dieser Flags sind relativ unwichtig, auf andere werde ich später eingehen.
Zusatzbemerkung: Oben kann man vielleicht den Eindruck haben, dass die Register nur für
bestimmte Zwecke gut sind. Das ist nicht so. Hier herrscht frohe Anarchie. So kann man zum
Beispiel weil einem danach ist und weil es irgendwie passt den Aktuellen Treibstoffverbrauch
eines virtuellen Autos in BP (also dem Basepointer) speichern. Das geht gut. Die
Allzweckregister sind sowieso für alles gut und die anderen auch, bis auf folgende
Ausnahmen: SP sollte nicht direkt verändert werden, IP geht gar nicht direkt, das Flagregister
auch nicht.
Die Segmentregister sollten besser Segmentadressen enthalten und sonst nichts.
Ja natürlich ich weiss LOOP nimmt seinen Counter nun mal nur in CX usw. aber das kommt noch
und sollte niemanden davon abhalten den Treibstoffverbrauch in BP zu speichern (zumindest im
allerschlimmsten Notfall)
So das wäre fürs Erste genug. Als nächstes werde ich kurz auf Hexadezimale und Binäre
Zahlen eingehen.
Zurück Weiter Inhalt