%AX = (%AH + %AL)
だから、なぜ%EAX = (%SOME_REGISTER + %AX)
はいくつかのレジスタ_%SOME_REGISTER
?
明確にするためだけに。 1970年代の初期のマイクロプロセッサ時代には、CPUには少数のレジスタと非常に限られた命令セットしかありませんでした。通常、演算ユニットは、「アキュムレータ」と呼ばれることが多い単一のCPUレジスタでのみ動作します。 8ビット8080およびZ80プロセッサのアキュムレータは「A」と呼ばれていました。 B、C、D、E、H、Lの6つの汎用8ビットレジスタがありました。これらの6つのレジスタを組み合わせて、BC、DE、HLの3つの16ビットレジスタを形成できました。内部的に、アキュムレータはフラグレジスタと組み合わされて、AF 16ビットレジスタを形成しました。
Intelが16ビット8086ファミリを開発したとき、8080コードを移植できるようにしたかったので、同じ基本レジスタ構造を維持しました。
8080/Z80 8086
A AX
BC BX
DE CX
HL DX
IX SI
IY DI
8ビットコードを移植する必要があるため、AX、BX、CXおよびDXの個々の8ビット部分を参照できる必要がありました。これらは、AXの下位および上位バイトに対してAL、AHと呼ばれ、BL/BH、CL/CHおよびDL/DHに対しても同様です。 Z80のIXとIYは16ビットポインターレジスタとしてのみ使用されていたため、SIとDIの2つの半分にアクセスする必要はありませんでした。
80386が1980年代半ばにリリースされたとき、すべてのレジスタの「拡張」バージョンを作成しました。したがって、AXはEAX、BXはEBXなどになりました。これらの新しい拡張レジスタの上位16ビットにアクセスする必要はなかったため、EAXH疑似レジスタは作成しませんでした。
AMDは、最初の64ビットプロセッサを製造するときに同じトリックを適用しました。 AXレジスタの64ビットバージョンはRAXと呼ばれます。したがって、次のようになりました。
|63..32|31..16|15-8|7-0|
|AH.|AL.|
|AX.....|
|EAX............|
|RAX...................|
ここには多くの回答が掲載されていますが、指定された質問に実際に答えているものはありません。上位16ビットのEAXまたは上位32ビットのRAXを直接エンコードするレジスタがないのはなぜですか?答えは、x86命令のエンコード自体の制限に要約されます。
16ビット履歴レッスン
Intelが8086を設計したとき、彼らは多くの命令に可変長エンコードスキームを使用しました。これは、POP AX
のような特定の非常に一般的な命令をシングルバイト(58)で表すことができ、MOV CX, [BX*4+BP+1023]
のようなまれな(しかし潜在的に有用な)命令は、たとえそれらを保存するのに数バイトかかりました(この例では、8B 8C FF 03)。
これは合理的な解決策のように思えるかもしれませんが、彼らが設計したとき、彼らは利用可能なスペースのほとんどを埋めました。したがって、たとえば、8つの個々のレジスタ(AX、CX、DX、BX、SP、BP、SI、DI)に対して8つのPOP
命令があり、それらはオペコード58から5Fを埋め、オペコード60はオペコード57(Push DI
)と同様に、完全に別のもの(PUSHA
)。それらの前後に何かのための余地はありません。セグメントレジスタのプッシュおよびポップ(概念的には汎用レジスタのプッシュおよびポップとほぼ同じ)でも、横にスペースがないため、別の場所(06/0E/16/1E前後)にエンコードする必要がありました。プッシュ/ポップの残りの指示。
同様に、MOV CX, [BX*4+BP+1023]
のような複雑な命令に使用される「mod r/m」バイトには、レジスタをエンコードするための3ビットしかありません。つまり、合計8つのレジスタのみを表すことができます。レジスタが8つしかない場合はこれで問題ありませんが、さらに多くのレジスタが必要な場合は、実際の問題が発生します。
(x86アーキテクチャには、これらすべてのバイト割り当ての優れたマップがあります: http://i.imgur.com/xfeWv.png 。プライマリマップにスペースが残っていないことに注意してください。 MMXとSSE命令)のおかげで、バイトが重複する命令、およびセカンダリ "0F"マップのどれだけが使用されるようになりましたか。
32および64ビットに向けて
CPU設計を16ビットから32ビットに拡張できるようにするために、設計上の問題がすでにあり、prefix bytesでそれを解決しました:特別な「66すべての標準16ビット命令の前のバイト。CPUは、16ビットバージョン(AX)ではなく32ビットバージョン(EAX)で同じ命令が必要であることを認識しています。設計の残りの部分は同じままで、CPUアーキテクチャ全体にまだ汎用レジスタが合計8つしかありませんでした。
アーキテクチャを64ビット(RAXおよび友人)に拡張するには、同様のハッカーを実行する必要がありました。そこで、「64ビット」を意味するプレフィックスコード(REX
、40-4F)のセットを追加することで問題を解決しました(さらに、「mod r/m」フィールドにさらに2ビットを追加しました)。また、誰も使用したことのない奇妙な古い命令を破棄し、新しいコードのためにバイトコードを再利用します。
8ビットレジスターの脇
質問すべき大きな質問の1つは、AHやALのような一体のものが、8つのレジスターの設計に本当に余裕がある場合に、そもそもどのように機能したかです。答えの最初の部分は、「Push AL
」のようなものはないということです。一部の命令は、単にバイトサイズのレジスターでまったく動作できません!できるのは、いくつかの特別な奇妙なもの(AAD
やXLAT
など)と "mod r/m"命令の特別なバージョンです: "mod r/m」バイト、これらの「拡張命令」は、16ビットのレジスタではなく8ビットのレジスタで動作するように反転できます。ちょうど8つの8ビットレジスタもあります:AL、CL、DL、BL、AH、CH、DH、およびBH(この順序で)、および利用可能な8つのレジスタスロットと非常にうまく並んでいます「mod r/m」バイト内。
Intelは、8086の設計は8080/8085と「ソース互換」であると想定されていたと述べました。8080には、8080/8085の各命令に対して同等の命令がありましたが、同じバイトコードは使用しませんでした(それらは近くさえありません)、新しいバイトコードを使用するようにプログラムを再コンパイル(再アセンブル)する必要があります。しかし、「ソース互換性」は古いソフトウェアの前進であり、8085の個々のA、B、Cなど、およびコンボ「BC」および「DE」レジスタが新しいプロセッサで動作することを許可しました。 「AL」、「BL」、「BX」、「DX」(またはマッピングが何であれ)と呼ばれます。
それが本当の答えです:IntelやAMDがEAXの上位16ビットレジスタやRAXの上位32ビットレジスタを意図的に「除外」したわけではありません:上位8ビットレジスタが奇妙な残り物であるということですアーキテクチャに下位互換性があるという要件を考えると、より大きなビットサイズで設計を複製することは非常に困難です。
パフォーマンスの考慮事項
これらの「高レジスタ」が追加されていない理由については、もう1つの考慮事項があります。最新のプロセッサアーキテクチャ内では、パフォーマンス上の理由から、可変サイズのレジスタは実際にはオーバーラップしません。 AXの一部であり、AXはEAXの一部ではなく、EAXはRAXの一部ではありません。これらはすべて内部の別個のレジスターであり、ユーザーがいずれかを操作すると、プロセッサーはその他の無効化フラグを設定します他のユーザーから読み取るときにデータをコピーする必要があることを認識できるようにします。
(例:AL = 5に設定した場合、プロセッサはAXを更新しません。しかし、AXから読み取ると、プロセッサはその5をALからAXの最下位ビットにすばやくコピーします。)
レジスタを分離しておくことで、CPUは目に見えないレジスタの名前変更など、あらゆる種類の賢明なことを実行してコードの実行速度を向上させることができますが、それはコードを使用するとslowerを実行することを意味しますプロセッサがストールして更新する必要があるため、小さなレジスタを大きなレジスタの一部として扱う古いパターン。この内部簿記のすべてが手に負えなくなるのを防ぐために、CPU設計者は、重複するレジスタを追加するのではなく、新しいプロセッサに個別のレジスタを追加することを賢明に選択しました。
(そして、はい、それは、現代のプロセッサーでは、「MOVZX EAX, value
」の古い、よりゆるやかな方法で行うよりも、明示的に「MOV AX, value / use EAX
」にしたほうが本当に速いことを意味します。)
結論
そうは言っても、IntelとAMDは本当に必要な場合、「重複する」レジスタを追加できますか?承知しました。十分な需要がある場合、それらをワームする方法があります。しかし、重要な歴史的手荷物、現在のアーキテクチャ上の制限、顕著なパフォーマンスの制限、および最近のほとんどのコードは非重複レジスタ用に最適化されたコンパイラによって生成されるという事実を考えると、すぐにそのようなものを追加することはほとんどありません。
昔の8ビット時代には、Aレジスタがありました。
16ビット時代には、16ビットのAXレジスタがありました。これは、8ビット値を使用したいときのために、AHとALの2つの8ビット部分に分割されていました。
32ビット時代には、32ビットのEAXレジスタが導入されましたが、AX、AH、およびALレジスタはすべて保持されていました。設計者は、EAXのビット16〜31をアドレス指定する新しい16ビットレジスタを導入する必要はないと感じていました。