Frage

%AX = (%AH + %AL)

Warum also nicht für einige Register %EAX = (%SOME_REGISTER + %AX) %SOME_REGISTER?

War es hilfreich?

Lösung

Nur für einige Klarstellung. In den frühen Tagen Mikroprozessor der 1970er Jahre, hatte CPUs nur eine kleine Anzahl von Registern und einen sehr begrenzten Befehlssatz. Typischerweise könnte die Recheneinheit nur auf einem einzigen CPU-Registern arbeiten, die oft als „Akkumulator“. Der Speicher auf den 8-Bit-8080 & Z80-Prozessoren wurde mit „A“ bezeichnet. Es gab 6 andere allgemeine Zwecke 8-Bit-Register: B, C, D, E, H & L. Diese sechs Register gepaart werden können 3 16-Bit-Register zu bilden: BC, DE und HL. Intern wurde der Sammler in Kombination mit den Flags die AF 16-Bit-Register zu bilden registrieren.

Wenn Intel entwickelt, um die 16-Bit-8086-Familie, sie wollten Port 8080 Code in der Lage sein, so hielten sie die gleiche Grundregisterstruktur:

8080/Z80  8086
A         AX
BC        BX
DE        CX
HL        DX
IX        SI    
IY        DI

Aufgrund der Notwendigkeit, Port 8-Bit-Code, den sie benötigt, um die einzelnen 8-Bit-Teile von AX, BX, CX & DX beziehen zu können. Dies wird AL, AH genannt für das niedrige und hohe Bytes von AX und so weiter für BL / BH, CL / CH & DL / DH. IX & IY auf dem Z80 wurde immer nur als 16-Bit-Zeigerregister verwendet, so gibt es keine Notwendigkeit, die beiden Hälften der SI & DI zuzugreifen war.

Wenn der 80386 wurde Mitte der 1980er Jahre veröffentlichte sie geschaffen „erweiterte“ Versionen aller Register. Also, AX wurde EAX, BX wurde EBX usw. Es bestand keine Notwendigkeit für den Zugriff auf 16 Bit dieser neuen erweiterten Register nach oben, so dass sie nicht ein EAXH Pseudoregister erstellen.

AMD angewandt, um den gleichen Trick, wenn sie die ersten 64-Bit-Prozessoren erzeugt. Die 64-Bit-Version des AX-Register RAX genannt. So, jetzt haben Sie etwas, das wie folgt aussieht:

|63..32|31..16|15-8|7-0|
               |AH.|AL.|
               |AX.....|
       |EAX............|
|RAX...................|

Andere Tipps

Es gibt geschrieben viele Antworten hier, aber keiner wirklich die gegebene Frage beantworten: Warum gibt es ein Register, das die hohen 16 Bits von EAX codiert direkt oder die hohen 32 Bits von RAX? Die Antwort läuft darauf hinaus, die Einschränkungen des x86-Befehls nach unten selbst codieren.

16-Bit-History Lesson

Als Intel die 8086 entworfen, benutzten sie ein Codierungsschema mit variabler Länge für viele der Anweisungen. Dies bedeutete, dass bestimmte extrem gemeinsame Anweisungen, wie POP AX, als ein einziges Byte (58) dargestellt werden könnten, während selten (aber immer noch potentiell nützlich) Anweisungen wie MOV CX, [BX*4+BP+1023] noch dargestellt werden könnten, auch wenn es mehrere Bytes nahm sie zu speichern (in dieses Beispiel 8B 8C FF 03).

Das mag wie eine vernünftige Lösung sein, aber wenn sie es entworfen, gefüllt sie den größten Teil der zur Verfügung stehenden Raum heraus . So zum Beispiel gab es acht POP Anweisungen für die acht einzelne Register (AX, CX, DX, BX, SP, BP, SI, DI), und sie ausgefüllt Opcodes 58 bis 5F und Opcode 60 war etwas völlig anderes ( PUSHA), wie es Opcode 57 (PUSH DI). Es gibt keinen Raum für irgendetwas nach links über oder vor denen. Auch drängte und die Segmentregister knallen - die konzeptionell nahezu identisch zu drängen und die allgemeinen Register popping - hatte in einem anderen Ort codiert wird (nach unten um 06 / 0E / 16 / 1E), nur weil es nicht war Raum neben der Rest der Push / Pop-Anweisungen.

Ebenso ist die „mod r / m“ byte für einen komplexen Befehl wie MOV CX, [BX*4+BP+1023] verwendet wird, hat nur drei Bits für das Register codiert, was bedeutet, dass es nur acht Register insgesamt darstellen. Das ist in Ordnung, wenn Sie nur acht Register, sondern stellt ein echtes Problem, wenn Sie mehr haben.

(Es gibt eine ausgezeichnete Karte alle diese Byte-Zuweisungen in der x86-Architektur hier: http://i.imgur.com/xfeWv .png . Beachten Sie, wie es keinen Raum ist in der primären Karte links, mit einigen Anweisungen Bytes überlappen, und sogar, wie viel von der sekundären „0F“ Karte verwendet wird nun dank der MMX und SSE-Befehle.)

In Richtung 32 und 64 Bits

Also auch das Design CPU zu ermöglichen, von 16 Bit auf 32 Bit erweitert werden, sie hatte bereits ein Design-Problem, und sie gelöst, dass mit Präfix Bytes : Durch das Hinzufügen eines speziellen „66“ Byte vor allen üblichen 16-Bit-Befehle, weiß die CPU Sie die gleiche Anweisung wollen, aber die 32-Bit-Version (EAX) anstelle der 16-Bit-Version (AX). Der Rest der Konstruktion gleich geblieben. Es gibt immer noch nur insgesamt acht waren Allzweckregister in der gesamten CPU-Architektur

ähnliche hackery mußte getan werden, um die Architektur zu 64-Bit (RAX und Freunde) zu verlängern; Dort wurde das Problem durch die Zugabe von noch einen anderen Satz von Präfixcodes (REX, 40-4F) gelöst, die „64-Bit“ (und effektiv hinzugefügt zwei weitere Bits nach „mod r / m“ -Feld) und auch Verwerfen seltsamen gemeint alte Anweisungen niemand jemals benutzt und ihren Byte-Codes für neuere Sachen Wiederverwendung.

Ein Abgesehen von 8-Bit-Registern

Eines der größeren Fragen zu stellen, dann ist, wie zum Teufel Dinge wie AH und AL jemals in erster Linie gearbeitet, wenn es in dem Entwurf für acht Register nur wirklich Raum ist. Der erste Teil der Antwort ist, dass es nicht so etwas wie „PUSH AL“ - einige Anweisungen einfach gar nicht auf den Byte-Größe Register arbeiten können! Die einzigen, die ein paar spezielle oddities (wie AAD und XLAT) und spezielle Versionen der „mod r / m“ Anweisungen sind können: Ein sehr spezifisches Bit umgedreht in dem „mod r / m“ Byte hat, diejenigen „erweiterten Anweisungen "könnte umgedreht auf den 8-Bit-Register anstelle der 16-Bit-diejenigen zu bedienen. Es passiert einfach so, dass es genau acht 8-Bit-Register sind, auch: AL, CL, DL, BL, AH, CH, DH und BH (in dieser Reihenfolge), und daß die Leitungen bis sehr gut mit dem acht Registern Slots in dem "mod r / m" Byte.

Intel bemerkt zu der Zeit, dass das 8086-Design sollte „Quelle kompatibel“ sein mit dem 8080/8085: Es gab eine äquivalente Anweisung in den 8086 für jeden der 8080/8085 Anweisungen, aber es hat nicht die Verwendung gleicher Byte-Codes (sie sind nicht einmal in der Nähe), und man müßte neu kompilieren (zusammenbauen) Ihr Programm, um es den neuen Byte-Codes zu verwenden. Aber „Quelle kompatibel“ war ein Weg für alte Software, und es erlaubte die 8085 der einzelne A, B, C, usw. und Combo „BC“ und „DE“ registriert noch auf den neuen Prozessor zu arbeiten, auch wenn sie jetzt genannt "AL" und "BL" und "BX" und "DX" (oder was auch immer die Abbildung war).

Das ist also wirklich die richtige Antwort: Es ist nicht, dass Intel oder AMD absichtlich „ausgelassen“ eineine hohes 16-Bit-Register für EAX oder ein hohes 32-Bit-Register für RAX: Es ist, dass die hochen 8-Bit-Register a sind seltsame Überbleibsel historische Anomalie, und ihr Design bei höheren Bit-Größen zu replizieren würden die Forderung gegeben wirklich schwierig sein, dass die Architektur rückwärtskompatibel sein.

A Leistungs Berücksichtigung

Es gibt eine weitere Überlegung, warum hat dieses „High-Register“, da nicht hinzugefügt worden ist, auch: Inside moderne Prozessorarchitekturen aus Leistungsgründen, die variabler Größe Register nicht tatsächlich für echte überlappen: AH und AL ist nicht Teil von AX und AX ist kein Teil von EAX, und EAX ist kein Teil von RAX: Sie sind alle separaten Register unter der Haube, und der Prozessor setzt eine Ungültigkeits Flagge auf dem anderen, wenn Sie manipulieren einer von ihnen, so dass es weiß, wird es brauchen, um die Daten zu kopieren, wenn Sie von den anderen lesen.

(Zum Beispiel:.. Wenn Sie setzen AL = 5, der Prozessor nicht AX nicht aktualisiert Aber wenn man dann von AX lesen, der Prozessor schnell kopiert, dass 5 von AL in der unteren Bits des AX)

Indem die Register trennen, die CPU alle möglichen kluge Dinge wie unsichtbare Register tun können umbenennen Code schneller laufen zu machen, aber das bedeutet, dass Ihr Code ausgeführt wird langsamer , wenn Sie die alte verwenden tun Muster der kleinen Register als Stücke von größeren Registern zu behandeln, da der Prozessor sich zum Stillstand kommen wird und zu aktualisieren. Um alle diese internen Buchführung zu halten von ihnen aus der Hand, wählten die CPU Designer weise getrennte Register auf den neueren Prozessoren hinzuzufügen, anstatt mehr überlappende Register hinzuzufügen.

(Und ja, das bedeutet, dass es wirklich schneller auf modernen Prozessoren ist explizit „MOVZX EAX, value“, als es die alte, nachlässige Weise von „MOV AX, value / use EAX“ zu tun.)

Fazit

Mit all das gesagt, könnten Intel und AMD hinzufügen mehr „überlappende“ registriert, wenn sie wirklich wirklich wollen? Sicher. Es gibt Möglichkeiten, um Wurm in ihnen, wenn es genug Nachfrage. Aber das bedeutende historische Gepäck gegeben, die aktuellen architektonischen Einschränkungen, die bemerkenswerten Leistungsbeschränkungen, und die Tatsache, dass die meisten Code in diesen Tage von Compilern für nicht überlappende Register optimieren erzeugt wird, ist es sehr unwahrscheinlich, dass sie solche Dinge in absehbarer Zeit hinzufügen werden.

In den alten 8-Bit-Tagen gibt das Register A war.

In den 16-Bit-Tagen waren die 16-Bit-AX-Register, die in zwei 8-Bit-Teile, AH und AL aufgeteilt wurden, für die damalige Zeit, wenn Sie wollten noch mit 8-Bit-Werten arbeiten.

In den 32-Bit-Tagen, die 32-Bit-EAX-Register eingeführt, aber die AX, AH und AL-Register wurden alle gehalten. Die Designer haben nicht das Gefühl es notwendig, ein neue 16-Bit-Register einzuführen, die Bits 16 bis 31 von EAX gerichtet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top