69

%AX = (%AH + %AL)

%EAX = (%SOME_REGISTER + %AX)では、いくつかのレジスタを使用しないのはなぜ%SOME_REGISTERですか?

4

3 に答える 3

137

明確にするために。1970 年代の初期のマイクロプロセッサの時代、CPU には少数のレジスタと非常に限られた命令セットしかありませんでした。通常、算術ユニットは、「アキュムレータ」と呼ばれることが多い単一の CPU レジスタでのみ動作できます。8 ビット 8080 および Z80 プロセッサのアキュムレータは「A」と呼ばれていました。他に 6 つの汎用 8 ビット レジスタがありました: B、C、D、E、H & L。内部的には、アキュムレータがフラグ レジスタと組み合わされて、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...................|
于 2008-10-23T02:40:26.593 に答える
33

ここには多くの回答が投稿されていますが、与えられた質問に実際に回答するものはありません: EAX の上位 16 ビットまたは RAX の上位 32 ビットを直接エンコードするレジスタがないのはなぜですか? 答えは、x86 命令エンコーディング自体の制限に要約されます。

16ビット履歴レッスン

Intel が 8086 を設計したとき、多くの命令に可変長のエンコード方式を使用しました。これは、 のような特定の非常に一般的な命令POP AXは 1 バイト (58) として表すことができる一方で、 のようなまれな (しかし潜在的に有用な) 命令MOV CX, [BX+SI+1023]は、それらを格納するのに数バイトかかる場合でも (この例では) 表すことができることを意味しました。 、8B 88 FF 03)。

これは合理的な解決策のように思えるかもしれませんが、彼らがそれを設計したとき、彼らは利用可能なスペースのほとんどを埋めました. したがって、たとえば、POP8 つの個々のレジスタ (AX、CX、DX、BX、SP、BP、SI、DI) には 8 つの命令があり、オペコード 58 から 5F を埋め、オペコード 60 はまったく別のものでした ( PUSHA) 。 、オペコード 57 ( PUSH DI) と同様です。それらの前後に何かを入れる余地はありません。セグメント レジスタのプッシュとポップ (概念的には汎用レジスタのプッシュとポップとほぼ同じ) でさえ、別の場所 (06/0E/16/1E 付近) にエンコードする必要がありました。残りのプッシュ/ポップ命令。

同様に、複雑な命令に使用される「mod r/m」バイトにはMOV CX, [BX+SI+1023]、レジスタをエンコードするためのビットが 3 つしかないため、合計で 8 つのレジスタしか表すことができません。レジスタが 8 つしかない場合は問題ありませんが、それ以上のレジスタが必要な場合は、実際の問題が生じます。

(x86 アーキテクチャでのこれらすべてのバイト割り当ての優れたマップがここにあります: http://i.imgur.com/xfeWv.png。プライマリ マップにスペースが残っていないことに注意してください。現在、MMX および SSE 命令のおかげで、セカンダリ "0F" マップの多くが使用されています。)

32 ビットと 64 ビットに向けて

したがって、CPU 設計を 16 ビットから 32 ビットに拡張できるようにするために、彼らはすでに設計上の問題を抱えていましたが、プレフィックス バイトでそれを解決しました。標準の 16 ビットのすべての前に特別な「66」バイトを追加することによってCPU は、同じ命令が必要であることを認識しますが、16 ビット バージョン (AX) ではなく 32 ビット バージョン (EAX) が必要です。設計の残りの部分は同じままでした。CPU アーキテクチャ全体で合計 8 つの汎用レジスタしかありませんでした。

アーキテクチャを 64 ビット (RAX など) に拡張するには、同様のハッキングが必要でした。そこでは、「64ビット」を意味するさらに別のプレフィックスコード(REX、40-4F)のセットを追加することで問題が解決され(さらに「mod r / m」フィールドにさらに2ビットが効果的に追加されました)、奇妙な古いものも破棄されます誰も使用したことのない命令と、新しいもののためにバイトコードを再利用する命令。

8 ビット レジスタの余談

したがって、尋ねるべきより大きな質問の 1 つは、設計に 8 つのレジスターの余地しかない場合、そもそも AH や AL のようなものがどのように機能したかということです。答えの最初の部分は、" " などというものは存在しないということですPUSH AL— 一部の命令は、バイトサイズのレジスタをまったく操作できません! できる唯一のものは、いくつかの特別な奇妙なことですAADXLAT) および "mod r/m" 命令の特別なバージョン: "mod r/m" バイトで特定のビットを反転させることにより、これらの「拡張命令」を反転して、 16ビットのもの。AL、CL、DL、BL、AH、CH、DH、および BH (この順序で) の 8 ビット レジスタもちょうど 8 つあり、利用可能な 8 つのレジスタ スロットと非常にうまく並んでいます。 「mod r/m」バイトで。

Intel は当時、8086 の設計は 8080/8085 と「ソース互換性がある」はずであると述べていました。 (それらは近くさえありません)、新しいバイトコードを使用するには、プログラムを再コンパイル(再アセンブル)する必要があります。しかし、「ソース互換性」は古いソフトウェアの前進であり、8085 の個々の A、B、C などと組み合わせた「BC」と「DE」レジスタは、たとえ現在でも新しいプロセッサで動作することを可能にしました。 「AL」と「BL」と「BX」と「DX」(またはマッピングが何であれ)と呼ばれます。

それが本当に本当の答えです:IntelまたはAMDがEAXの上位16ビットレジスタ、またはRAXの上位32ビットレジスタを意図的に「除外」したわけではありません:上位8ビットレジスタが奇妙な残りの歴史的レジスタであるということですアーキテクチャに下位互換性があるという要件を考えると、より高いビットサイズで設計を複製することは非常に困難です。

パフォーマンスに関する考慮事項

なぜこれらの「上位レジスタ」が追加されなかったのかについては、もう 1 つの考慮事項があります。最新のプロセッサ アーキテクチャの内部では、パフォーマンス上の理由から、可変サイズのレジスタは実際にはオーバーラップしていません。 t は AX の一部であり、AX は EAX の一部ではなく、EAX は RAX の一部ではありません。これらはすべて、フードの下にある個別のレジスタであり、プロセッサは、いずれかを操作すると、他のレジスタに無効化フラグを設定します。他のデータから読み取るときにデータをコピーする必要があることを認識できるようにします。

(例: AL = 5 を設定すると、プロセッサは AX を更新しません。ただし、その後 AX から読み取ると、プロセッサはその 5 を AL から AX の下位ビットにすばやくコピーします。)

レジスタを分離しておくことで、CPU は目に見えないレジスタの名前変更など、あらゆる種類の巧妙なことを実行してコードを高速化できますが、小さなレジスタを大きなレジスタの断片として扱う古いパターンを使用すると、コードの実行が遅くなります。これは、プロセッサがそれらをストールして更新する必要があるためです。この内部簿記のすべてが手に負えなくなるのを防ぐために、CPU 設計者は、重複するレジスタを追加するのではなく、新しいプロセッサに個別のレジスタを追加することを賢明に選択しました。

(そして、つまり、最新のプロセッサMOVZX EAX, valueでは、古くてずさんな方法で " MOV AX, value / use EAX" 実行するよりも、明示的に " " 実行する方が実際に高速であることを意味します。)

結論

そうは言っても、IntelとAMDが本当に望むなら、「重複する」レジスタをさらに追加できますか? もちろん。十分な需要があれば、それらをワームする方法があります。しかし、過去の重要な荷物、現在のアーキテクチャの制限、顕著なパフォーマンスの制限、および最近のほとんどのコードが重複しないレジスタ用に最適化されたコンパイラによって生成されているという事実を考えると、すぐにそのようなものを追加する可能性はほとんどありません.

于 2015-09-09T06:21:12.587 に答える
26

昔の 8 ビット時代には、A レジスタがありました。

16 ビットの時代には、16 ビットの AX レジスタがありました。これは 2 つの 8 ビット部分、AH と AL に分割され、まだ 8 ビット値で作業したい場合に備えていました。

32 ビット時代には、32 ビットの EAX レジスタが導入されましたが、AX、AH、および AL レジスタはすべて保持されていました。設計者は、EAX のビット 16 ~ 31 をアドレス指定する新しい 16 ビット レジスタを導入する必要性を感じていませんでした。

于 2008-10-23T01:41:50.470 に答える