EAXの上位バイトを含むレジスタがないのはなぜですか?

StackOverflow https://stackoverflow.com/questions/228200

  •  03-07-2019
  •  | 
  •  

質問

%AX =(%AH +%AL)

では、いくつかのレジスタ%SOME_REGISTER に対して%EAX =(%SOME_REGISTER +%AX)を選択しないのはなぜですか?

役に立ちましたか?

解決

説明のためだけに。 1970年代の初期のマイクロプロセッサ時代には、CPUには少数のレジスタと非常に限られた命令セットしかありませんでした。通常、演算ユニットは、「アキュムレータ」と呼ばれることが多い単一のCPUレジスタでのみ動作します。 8ビット8080&のアキュムレータ。 Z80プロセッサは「A」と呼ばれていました。他に6つの汎用8ビットレジスタがありました:B、C、D、E、H& L.これらの6つのレジスタを組み合わせて、3つの16ビットレジスタを形成できます。 HL。内部的に、アキュムレータはフラグレジスタと組み合わされて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&の個々の8ビット部分を参照できるようにする必要がありました。 DX。これらは、低&のためにAL、AHと呼ばれます。 BL / BH、CL / CH&のAXなどの上位バイトDL / DH。 IX& Z80のIYは16ビットポインタレジスタとしてのみ使用されていたため、SIの2つの半分にアクセスする必要はありませんでした。 DI。

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...................|

他のヒント

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

16ビット履歴レッスン

Intelが8086を設計したとき、彼らは多くの命令に可変長エンコード方式を使用していました。これは、 POP AX のような特定の非常に一般的な命令は1バイト(58)として表されるが、 MOV CX、[BX * 4 + BP + 1023] は、それらを保存するのに数バイトかかったとしても、表現できます(この例では、8B 8C FF 03)。

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

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

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

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

CPUデザインを16ビットから32ビットに拡張できるようにするために、既にデザインの問題があり、プレフィックスバイトでそれを解決しました。特別な「66」を追加することにより、すべての標準16ビット命令の前に1バイトがあれば、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」で非常に特定のビットを反転させることにより、バイト、これらの「拡張命令」操作するために反転することができます

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

16ビットの時代には、16ビットのAXレジスタがあり、8ビット値を処理したいときのために、AHとALの2つの8ビット部分に分割されていました。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top