Suche…


16-Bit-Register

Bei der Definition des ursprünglichen 8086 durch Intel handelte es sich um einen 16-Bit-Prozessor mit einem 20-Bit-Adressbus (siehe unten). Sie definierten 8 allgemeine 16-Bit-Register - gaben ihnen jedoch bestimmte Rollen für bestimmte Anweisungen:

  • AX Das Akkumulatorregister.
    Viele Opcodes nahmen dieses Register entweder an oder waren schneller, wenn es angegeben wurde.
  • DX Das Datenregister.
    Dies wurde manchmal als die hohen 16 Bits eines 32-Bit-Werts mit AX kombiniert, beispielsweise als Ergebnis einer Multiplikation.
  • CX Das Count-Register.
    Dies wurde in einer Reihe schleifenorientierter Anweisungen als impliziter Zähler für diese Schleifen verwendet - zum Beispiel LOOPNE (Schleife, falls nicht gleich) und REP (wiederholtes Verschieben / Vergleichen).
  • BX Das Basisregister.
    Dies kann verwendet werden, um die Basis einer Struktur im Speicher zu indizieren - keines der oben genannten Register könnte zum direkten Indexieren in den Speicher verwendet werden.
  • SI Das Quellindexregister.
    Dies war der implizite Quellenindex für bestimmte Verschiebungs- und Vergleichsoperationen im Speicher.
  • DI Das Zielindexregister.
    Dies war der implizite Zielindex im Speicher für bestimmte Verschiebungs- und Vergleichsoperationen.
  • SP Das Stack-Pointer-Register.
    Dies ist das am wenigsten generelle Register im Set! Es zeigte auf die aktuelle Position im Stack, die explizit für PUSH und POP Operationen verwendet wurde, implizit für CALL und RET mit Unterprogrammen und VERY implizit während Interrupts. Daher war die Verwendung für alles andere gefährlich für Ihr Programm!
  • BP Das Basiszeigerregister.
    Wenn Unterprogramme andere Unterprogramme aufrufen, enthält der Stapel mehrere "Stapelrahmen". BP könnte zum Speichern des aktuellen Stack-Frames verwendet werden. Wenn eine neue Subroutine aufgerufen wurde, konnte sie auf dem Stack gespeichert, der neue Stack-Frame erstellt und verwendet werden. Bei Rückkehr aus der inneren Subroutine konnte der alte Stack-Frame-Wert wiederhergestellt werden .

Anmerkungen:

  1. Die ersten drei Register können nicht zum Indizieren in den Speicher verwendet werden.

  2. BX , SI und DI indexieren standardmäßig in das aktuelle Datensegment (siehe unten).

     MOV    AX, [BX+5]     ; Point into Data Segment
     MOV    AX, ES:[DI+5]  ; Override into Extra Segment
    
  3. Wenn DI in Speicher-zu-Speicher-Operationen wie MOVS und CMPS , wird ausschließlich das Extra-Segment verwendet (siehe unten). Dies kann nicht überschrieben werden.

  4. SP und BP verwenden standardmäßig das Stapelsegment (siehe unten).

32-Bit-Register

Als Intel den 80386 produzierte, wurde ein Upgrade von einem 16-Bit-Prozessor auf einen 32-Bit-Prozessor durchgeführt. 32-Bit-Verarbeitung bedeutet zwei Dinge: Sowohl die zu manipulierenden Daten waren 32-Bit als auch die Speicheradressen, auf die zugegriffen wurde, waren 32-Bit. Um dies zu erreichen, aber immer noch kompatibel zu ihren früheren Prozessoren, haben sie völlig neue Modi für den Prozessor eingeführt. Es war entweder im 16-Bit-Modus oder im 32-Bit-Modus - aber Sie können diesen Modus Anweisungsweise für entweder Daten, Adressierung oder beides außer Kraft setzen!

Zunächst mussten 32-Bit-Register definiert werden. Sie haben dies getan, indem sie einfach die vorhandenen acht von 16 Bit auf 32 Bit erweitert und ihnen "erweiterte" Namen mit einem E Präfix gegeben haben: EAX , EBX , ECX , EDX , ESI , EDI , EBP und ESP . Die unteren 16 Bits dieser Register waren die gleichen wie zuvor, aber die oberen Hälften der Register standen für 32-Bit-Operationen wie ADD und CMP . Die oberen Hälften waren nicht wie bei den 8-Bit-Registern separat zugänglich.

Der Prozessor musste über einen separaten 16-Bit- und 32-Bit-Modus verfügen, da Intel für viele Operationen die gleichen Opcodes verwendete: CMP AX,DX im 16-Bit-Modus und CMP EAX,EDX im 32-Bit-Modus hatten genau dieselben Opcodes ! Dies bedeutet, dass derselbe Code NICHT in beiden Modi ausgeführt werden kann:

Der Opcode für "Sofort in AX " lautet 0xB8 , gefolgt von zwei Bytes des unmittelbaren Werts: 0xB8 0x12 0x34

Der Opcode für "Sofort in EAX " lautet 0xB8 , gefolgt von vier Bytes des unmittelbaren Werts: 0xB8 0x12 0x34 0x56 0x78

Der Assember muss also wissen, in welchem ​​Modus sich der Prozessor befindet, wenn er den Code ausführt, damit er weiß, dass er die richtige Anzahl von Bytes ausgibt.

8-Bit-Register

Bei den ersten vier 16-Bit-Registern kann auf die Bytes der oberen und unteren Hälfte direkt als eigene Register zugegriffen werden:

  • AH und AL sind die oberen und unteren Hälften des AX Registers.
  • BH und BL sind die High- und Low-Hälfte des BX Registers.
  • CH und CL sind die High- und Low-Hälfte des CX Registers.
  • DH und DL sind die High- und Low-Hälfte des DX Registers.

Beachten Sie, dass dies bedeutet, dass durch das Ändern von AH oder AL auch AX sofort geändert wird! Beachten Sie auch, dass jede Operation in einem 8-Bit-Register keinen Einfluss auf den "Partner" haben kann. 0xFF AL so hochgezählt wird, dass es von 0xFF zu 0x00 0xFF , würde sich AH nicht ändern.

64-Bit-Register haben auch 8-Bit-Versionen, die ihre niedrigeren Bytes darstellen:

  • SIL für RSI
  • DIL für RDI
  • BPL für RBP
  • SPL für RSP

Gleiches gilt für die Register R8 bis R15 : Ihre jeweiligen unteren Byte-Teile werden als R8B R15B .

Segmentregister

Segmentierung

Als Intel den ursprünglichen 8086 entwarf, gab es bereits eine Reihe von 8-Bit-Prozessoren, die über 16-Bit-Fähigkeiten verfügten. Sie wollten jedoch einen echten 16-Bit-Prozessor herstellen. Sie wollten auch etwas Besseres und Stärkeres produzieren als das, was es bereits gibt, und deshalb auf mehr als 65.536 Bytes an Speicher zugreifen, die von 16-Bit-Adressierungsregistern impliziert werden.

Ursprüngliche Segmentregister

Sie implementierten die Idee von "Segmenten" - einem 64-Kilobyte-Speicherblock, der von den 16-Bit-Adressregistern indiziert wird - und könnte neu adressiert werden, um verschiedene Bereiche des Gesamtspeichers zu adressieren. Um diese Segmentbasen zu halten, wurden Segmentregister eingeschlossen:

  • CS Das Codesegmentregister.
    Dies enthält den Abschnitt des Codes, der gerade ausgeführt wird, indiziert durch das implizite IP Register (Instruction Pointer).
  • DS Das Datensegmentregister.
    Dies enthält das Standardsegment für Daten, die vom Programm bearbeitet werden.
  • ES Das Zusatzsegmentregister.
    Dies enthält ein zweites Datensegment für gleichzeitige Datenoperationen über den gesamten Speicher.
  • SS Das Stack-Segmentregister.
    Dies enthält das Speichersegment, das den aktuellen Stapel enthält.

Segmentgröße

Die Segmentregister können beliebig groß sein, aber da sie 16 Bit breit sind, ist es leicht, mit den anderen Registern zusammenzuarbeiten. Die nächste Frage war: Sollten sich die Segmente überlappen und wenn ja, wie viel? Die Antwort auf diese Frage würde die gesamte Speichergröße bestimmen, auf die zugegriffen werden könnte.

Wenn es überhaupt keine Überlappung gab, dann wäre der Adressraum 32 Bit - 4 Gigabyte - eine damals völlig unbekannte Größe! Eine "natürliche" Überlappung von 8 Bit würde einen 24-Bit-Adressraum oder 16 Megabyte erzeugen. Am Ende entschied sich Intel dafür, vier weitere Adress-Pins auf dem Prozessor zu speichern, indem der Adressraum mit einer Überlappung von 12 Bit auf 1 Megabyte erhöht wurde - dies war für die Zeit ausreichend groß!

Weitere Segmentregister!

Als Intel den 80386 entwarf, erkannten sie, dass die vorhandene Gruppe von 4 Segmentregistern nicht ausreichte, um die Komplexität der Programme zu unterstützen, die sie unterstützen wollten. Also fügten sie zwei weitere hinzu:

  • FS Das Fernsegmentregister
  • GS Das globale Segmentregister

Diese neuen Segmentregister hatten keine durch den Prozessor erzwungenen Verwendungen: Sie waren lediglich für das, was der Programmierer wollte, verfügbar.

Einige sagen, dass die Namen gewählt wurden, um einfach das Thema C , D , E des bestehenden Sets fortzusetzen ...

64-Bit-Register

AMD ist ein Prozessorhersteller, der das Design des 80386 von Intel für die Herstellung kompatibler, aber konkurrierender Versionen lizenziert hatte. Sie haben interne Änderungen am Design vorgenommen, um den Durchsatz oder andere Verbesserungen des Designs zu verbessern, während sie dennoch die gleichen Programme ausführen können.

Für Intel gab es eine 64-Bit-Erweiterung für das 32-Bit-Design von Intel und der erste 64-Bit-Chip, auf dem noch 32-Bit-x86-Code ausgeführt werden konnte. Intel folgte dem Design von AMD in seinen Versionen der 64-Bit-Architektur.

Das 64-Bit-Design hat eine Reihe von Änderungen am Registersatz vorgenommen und ist dennoch abwärtskompatibel:

  • Die vorhandenen Universalregister wurden auf 64 Bit erweitert und mit einem R Präfix bezeichnet: RAX , RBX , RCX , RDX , RSI , RDI , RBP und RSP .

    Die unteren Hälften dieser Register waren wieder dieselben E Präfix-Register wie zuvor, und auf die oberen Hälften konnte nicht unabhängig zugegriffen werden.

  • 8 weitere 64-Bit-Register wurden hinzugefügt und nicht benannt, sondern lediglich nummeriert: R8 , R9 , R10 , R11 , R12 , R13 , R14 und R15 .
    • Die niedrige 32-Bit-Hälfte dieser Register besteht aus R8D bis R15D (D für DWORD wie üblich).
    • Auf die untersten 16 Bits dieser Register kann zugegriffen werden, indem ein W an den Registernamen R8W : R8W bis R15W .
  • Auf die untersten 8 Bits aller 16 Register kann jetzt zugegriffen werden:
    • Die traditionellen AL , BL , CL und DL ;
    • Die niedrigen Bytes der (traditionellen) Zeigerregister: SIL , DIL , BPL und SPL ;
    • Und die niedrigen Bytes der 8 neuen Register: R8B bis R15B .
    • Auf AH , BH , CH und DH jedoch nicht in Befehlen DH werden, die ein REX-Präfix verwenden (für 64-Bit-Operandengröße oder für den Zugriff auf R8-R15 oder für den Zugriff auf SIL , DIL , BPL oder SPL ). Bei einem REX-Präfix bedeutet das Maschinencode-Bitmuster, das früher AH bedeutete, SPL usw. Siehe Tabelle 3-1 des Intels Anweisungshandbuchs (Band 2).

Beim Schreiben in ein 32-Bit-Register werden immer die oberen 32 Bit des Registers mit voller Breite auf Null gesetzt, im Gegensatz zum Schreiben in ein 8- oder 16-Bit-Register (das mit dem alten Wert zusammengeführt wird, was eine zusätzliche Abhängigkeit für die Ausführung außerhalb der Reihenfolge darstellt ).

Flaggen registrieren

Wenn die x86 Arithmetic Logic Unit (ALU) Operationen wie NOT und ADD , werden die Ergebnisse dieser Operationen ("Null", "Überlauf", "Negativ") in einem speziellen 16-Bit- FLAGS Register FLAGS . 32-Bit-Prozessoren haben dies auf 32 Bit aufgerüstet und EFLAGS , während 64-Bit-Prozessoren auf 64 Bit aufgerüstet und RFLAGS .

Bedingungscodes

Aber unabhängig vom Namen ist das Register nicht direkt zugänglich (abgesehen von ein paar Anweisungen - siehe unten). Stattdessen wird in bestimmten Anweisungen auf einzelne Flags verwiesen, z. B. bedingter Sprung oder bedingter Satz ( Jcc und SETcc wobei cc "Bedingungscode" bedeutet und auf die folgende Tabelle verweist:

Bedingungscode Name Definition
E , Z Gleich Null ZF == 1
NE , NZ Nicht gleich, nicht Null ZF == 0
O Überlauf OF == 1
NO Kein Überlauf OF == 0
S Unterzeichnet SF == 1
NS Nicht unterschrieben SF == 0
P Parität PF == 1
NP Keine Parität PF == 0
-------------- ---- ----------
C , B , NAE Tragen Sie unten, nicht oben oder gleich CF = 1
NC , NB , AE Kein Carry, nicht darunter, oben oder gleich CF == 0
A , NBE Oben, nicht darunter oder gleich CF == 0 und ZF == 0
NA , BE Nicht über, unter oder gleich CF == 1 oder ZF == 1
--------------- ---- ----------
GE , NL Größer oder gleich, nicht weniger SF == OF
NGE , L Nicht größer oder gleich, weniger SF ! = OF
G , NLE Größer, nicht weniger oder gleich ZF == 0 und SF == OF
NG , LE Nicht größer, kleiner oder gleich ZF == 1 oder SF ! = OF

In 16 Bits ist das Subtrahieren von 1 von 0 entweder 65,535 oder -1 je nachdem, ob eine vorzeichenlose oder vorzeichenbehaftete Arithmetik verwendet wird. Das Ziel enthält jedoch 0xFFFF . Nur durch die Interpretation der Bedingungscodes ist die Bedeutung klar. Noch 0x8000 ist es, wenn 1 von 0x8000 subtrahiert 0x8000 : In vorzeichenloser Arithmetik ändert sich lediglich 32,768 in 32,767 ; In der signierten Arithmetik ändert sich -32,768 in 32,767 - ein viel bemerkenswerterer Überlauf!

Die Bedingungscodes sind in der Tabelle in drei Blöcke gruppiert: vorzeichenlos, vorzeichenlos und vorzeichenbehaftet. Die Benennung innerhalb der letzten beiden Blöcke verwendet "Vor" und "Unter" für unsigniert und "Größer" oder "Weniger" für Vorzeichen. JB wäre also "Jump if Below" (unsigned), während JL "Jump if Less" (signiert) wäre.

FLAGS Zugriff auf FLAGS

Die oben genannten Bedingungscodes sind nützlich, um vordefinierte Konzepte zu interpretieren, die eigentlichen Flag-Bits stehen jedoch auch direkt mit den folgenden beiden Anweisungen zur Verfügung:

  • LAHF AH Register mit Flags laden
  • SAHF AH Register in Flags SAHF

Mit diesen Anweisungen werden nur bestimmte Flags kopiert. Das gesamte FLAGS / EFLAGS / RFLAGS Register kann auf dem Stack gespeichert oder wiederhergestellt werden:

  • PUSHF / POPF 16-Bit- FLAGS auf / aus dem Stack PUSHF / POPF
  • PUSHFD / POPFD 32-Bit- EFLAGS auf / aus dem Stack PUSHFD / POPFD
  • PUSHFQ / POPFQ Push / Pop-64-Bit- RFLAGS / auf den Stack

Beachten Sie, dass Interrupts die aktuelle [R/E]FLAGS Registrierung automatisch speichern und wiederherstellen.

Andere Flaggen

Neben den oben beschriebenen ALU-Flags definiert das FLAGS Register weitere Flags für den FLAGS :

  • IF das Interrupt-Flag.
    Dies wird mit dem STI Befehl festgelegt, um Interrupts global zu aktivieren, und mit dem CLI Befehl gelöscht, um Interrupts global zu deaktivieren.
  • DF Die Richtungsflagge.
    Speicher-zu-Speicher-Operationen wie CMPS und MOVS (zum Vergleichen und Verschieben zwischen Speicherplätzen) MOVS oder verringern automatisch die Indexregister als Teil der Anweisung. Das DF Flag gibt an, welches geschieht: Wenn mit der CLD Anweisung gelöscht, werden sie inkrementiert. Wenn mit der STD Anweisung festgelegt, werden sie dekrementiert.
  • TF Die Fallenflagge. Dies ist ein Debug-Flag. Durch Setzen dieser Option wird der Prozessor in den Modus "Einzelschritt" versetzt: Nach Ausführung jeder Anweisung wird der "Einzelschritt-Interrupt-Handler" aufgerufen, von dem erwartet wird, dass er von einem Debugger verarbeitet wird. Es gibt keine Anweisungen zum Setzen oder Löschen dieses Flags: Sie müssen das Bit bearbeiten, während es sich im Speicher befindet.

80286 Flaggen

Um die neuen Multitasking-Funktionen des 80286 zu unterstützen, fügte Intel dem FLAGS Register zusätzliche Flags hinzu:

  • IOPL Die E / A- IOPL .
    Zum Schutz von Multitasking-Code benötigten einige Aufgaben Berechtigungen für den Zugriff auf E / A-Ports, während andere für den Zugriff auf sie gesperrt werden mussten. Intel führte eine Privilege-Skala mit vier Stufen ein, wobei 00 2 die höchste Priorität und 11 2 die niedrigste Priorität hatte. Wenn IOPL unter der aktuellen IOPL lag, würde jeder Versuch, auf E / A-Ports zuzugreifen oder Interrupts zu aktivieren oder zu deaktivieren, stattdessen eine allgemeine Schutzverletzung verursachen.
  • NT Flag für geschachtelte Aufgaben
    Dieses Flag wurde gesetzt, wenn eine Task CALL andere Task CALL , was zu einem Kontextwechsel führte. Das gesetzte Flag wies den Prozessor an, einen Kontextwechsel durchzuführen, wenn der RET ausgeführt wurde.

80386 Flaggen

Die '386 benötigte zusätzliche Flags, um die in den Prozessor integrierten zusätzlichen Funktionen zu unterstützen.

  • RF Das Resume-Flag.
    Die `386 fügte Debug-Register hinzu, die den Debugger bei verschiedenen Hardware-Zugriffen aufrufen konnten, z. B. Lesen, Schreiben oder Ausführen eines bestimmten Speicherorts. Wenn der Debug-Handler jedoch zurückkehrt, um die Anweisung auszuführen, würde der Zugriff den Debug-Handler sofort erneut aufrufen! Zumindest wäre dies der Fall, wenn es nicht für das Resume-Flag wäre, das bei der Eingabe in den Debug-Handler automatisch gesetzt und nach jeder Anweisung automatisch gelöscht wird. Wenn das Resume-Flag gesetzt ist, wird der Debug-Handler nicht aufgerufen.
  • VM Das virtuelle 8086-Flag.
    Um älteren 16-Bit-Code sowie neueren 32-Bit-Code zu unterstützen, kann der 80386 16-Bit-Tasks in einem "Virtual 8086" -Modus mithilfe eines Virtual 8086-Managers ausführen. Das VM Flag zeigte an, dass es sich bei dieser Aufgabe um eine virtuelle 8086-Aufgabe handelt.

80486 Flaggen

Mit der Verbesserung der Intel-Architektur wurde diese Technologie durch Caches und Superskalar-Ausführung schneller. Das musste den Zugriff auf das System durch Annahmen optimieren. Um diese Annahmen zu kontrollieren, wurden mehr Flaggen benötigt:

  • AC Ausrichtungsüberprüfungsflag Die x86-Architektur konnte immer auf Multi-Byte-Speicherwerte an jeder Byte-Grenze zugreifen, im Gegensatz zu einigen Architekturen, bei denen eine Größenanpassung erforderlich war (4-Byte-Werte mussten auf 4-Byte-Grenzen liegen). Dies war jedoch weniger effizient, da für den Zugriff auf nicht ausgerichtete Daten mehrere Speicherzugriffe erforderlich waren. Wenn das AC Flag gesetzt wurde, würde ein nicht ausgerichteter Zugriff eine Ausnahme auslösen, anstatt den Code auszuführen. Auf diese Weise könnte der Code während der Entwicklung mit AC Set verbessert werden, er wurde jedoch für den Produktionscode deaktiviert.

Pentiumflaggen

Der Pentium fügte weitere Unterstützung für die Virtualisierung hinzu sowie die CPUID Anweisung:

  • VIF Das Flag für virtuelle Unterbrechungen.
    Dies ist eine virtuelle Kopie der IF dieser Task - unabhängig davon, ob diese Task Interrupts deaktivieren möchte oder nicht, ohne dass dies Auswirkungen auf globale Interrupts hat.
  • VIP Das Kennzeichen für die Unterbrechung der virtuellen Unterbrechung.
    Dies zeigt an, dass ein Interrupt von VIF virtuell blockiert wurde. Wenn der Task einen STI ausführt, kann ein virtueller Interrupt ausgelöst werden.
  • ID Das CPUID Flag, das zugelassen wurde.
    Gibt an, ob diese Task die CPUID Anweisung ausführen soll. Ein virtueller Monitor könnte dies nicht zulassen und den anfordernden Task "belügen", wenn er die Anweisung ausführt.


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow