x86アセンブリで、 16ビットの「リアルモード」で使用できるのに、32ビットモードでeRx
は使用できないのはなぜですか。rRx
例えば:
BITS 16
mov bx, 1
mov eax, 2
正しく組み立ておよび分解します。以前にWin2kブートローダーを分解し、への参照を見つけたので、それは機能しますeax
。
しかし、64ビットプロセッサでも、32ビットの「プロテクトモード」ではアクセスできないのはrRx
なぜですか。
x86アセンブリで、 16ビットの「リアルモード」で使用できるのに、32ビットモードでeRx
は使用できないのはなぜですか。rRx
例えば:
BITS 16
mov bx, 1
mov eax, 2
正しく組み立ておよび分解します。以前にWin2kブートローダーを分解し、への参照を見つけたので、それは機能しますeax
。
しかし、64ビットプロセッサでも、32ビットの「プロテクトモード」ではアクセスできないのはrRx
なぜですか。
この理由は、64ビットモードが特定の場所で命令のデコードを変更するためです。つまり、64ビットのオペランドサイズを示すために使用されるプレフィックスバイト/レジスタ幅を64ビットに拡張/レジスタの使用を「新しい」R8
..R15
レジスタに拡張できるようにするためです。これらは、x86(CPU動作モードに依存しない)に一般的な「代替サイズプレフィックス」(0x66
)とは異なり、16ビットモードの場合はオペランド/レジスタサイズを16ビットから32ビットに変更し、16ビットモードの場合は32ビットから16ビットに変更します。 32ビットモード。
いわゆるプレフィックスは..REX
としてエンコードされ、CPUが64ビットモードで動作している場合にのみプレフィックスとして有効です。どうしてこんなことに ?さて、前述のように、命令のデコードを変更しましたが、これらのオペコードは実際には、従来のx86の/の1バイトバージョンにマップされます。
これは、16/32ビット命令セットのあいまいさのために可能です-またはのいずれかです。64ビットモードでは、命令デコーダーはこれのみを受け入れます。一方、示されているように、はプレフィックスの1つになります。0x40
0x4f
inc <reg>
dec <reg>
inc EAX
0x40
0xff 0xc0
0xff 0xc0
0x40
REX
したがって、これらの64ビットオペランドサイズのプレフィックスは16ビット/ 32ビットモードには存在しませんinc
( /dec
操作の場合は...)。したがって、16ビット/32ビットx86コードが「64ビット操作を実行したい」と述べる方法はありません。 。
例として、オペランドサイズが異なるいくつかの命令のアセンブリ/オペコードを次に示します。
64ビット32ビットオプション132ビットオプション2命令 ================================================== =========== fe c8 fe c8-dec al 66 ff c8 66 ff c8 66 48 dec ax ff c8 ff c8 48 dec eax 48 ff c8 --- dec rax
ご覧のとおり、64ビットはの1バイトバージョンを認識していませんdec eax
が、代わりに0x48
「これを64ビット操作にする」という命令プレフィックス(いくつかの1つ)として認識しています。
設計、CPU設計により、64ビット以外のモードで64ビットレジスタにアクセスすることはできません。
設計上、16ビットモードで32ビットレジスタにアクセスすることもできます。これを行うには、オペランドサイズプレフィックス(0x66
)およびアドレスサイズプレフィックス( )と呼ばれる特別な命令プレフィックスを使用します0x67
。
非64ビットモードで64ビットレジスタに到達するための特別な命令プレフィックスはありません。
32ビットモードでは、それを追加するのに十分なオペコード/プレフィックスコーディングスペースが残っていませんでした。これは、386が286を拡張したときとは異なり、プレフィックスに未使用のバイトがいくつかありました。
0x4?
64ビットモードで64ビットのオペランドサイズを指定するために必要なREXプレフィックスは、32ビットおよび16ビットモードのinc
/命令です。dec
AMD64は、必要なプレフィックス用のスペースを確保するために、一部のバイトの意味を変更する必要がありました。32ビットモードへの同じ変更は、既存のバイナリと互換性がありません。
ええと、80286を使用している場合、それは機能しません!使用しているコンピューターは、16ビットレジスタと32ビットレジスタの両方を備えているが64ビットレジスタを備えていない32ビットCPUです。64ビットCPUでも動作します。