ではインテルのマニュアルのx86-64のツアー、私が読んで
おそらく最も驚くべき事実は
MOV EAX, EBX
、RAX
レジスタなどの上位32ビットを自動的にゼロにするなどの命令です。
同じ出典で引用されているIntelのドキュメント(手動の基本アーキテクチャで64ビットモードの3.4.1.1汎用レジスター)は、次のように述べています。
- 64ビットのオペランドは、宛先の汎用レジスターで64ビットの結果を生成します。
- 32ビットのオペランドは32ビットの結果を生成し、デスティネーションの汎用レジスターで64ビットの結果にゼロ拡張します。
- 8ビットおよび16ビットのオペランドは、8ビットまたは16ビットの結果を生成します。デスティネーション汎用レジスタの上位56ビットまたは48ビットは、それぞれ操作によって変更されません。8ビットまたは16ビット演算の結果が64ビットのアドレス計算を目的としている場合は、明示的にレジスタを完全な64ビットに符号拡張します。
x86-32およびx86-64アセンブリでは、次のような16ビット命令
mov ax, bx
eaxの上位ワードがゼロになるこの種の「奇妙な」動作を表示しないでください。
したがって、この動作が導入された理由は何ですか?一見すると論理的に見えないようです(ただし、x86-32アセンブリの癖に慣れているためかもしれません)。
r32
は、マージするのではなく、上位32をゼロにします。たとえば、一部のアセンブラはで置き換えpmovmskb r64, xmm
られpmovmskb r32, xmm
、REXを保存します。これは、64ビットの宛先バージョンが同じように動作するためです。マニュアルの「操作」セクションでは、32/64ビットdestと64/128 / 256bソースの6つの組み合わせすべてを個別にリストしていますが、r32形式の暗黙のゼロ拡張は、r64形式の明示的なゼロ拡張と重複しています。HWの実装に興味があります...
xor eax,eax
またはxor r8d,r8d
RAXまたはR8をゼロにするための最良の方法です(RAXのREXプレフィックスを保存すると、64ビットXORはSilvermontでは特別に処理されません)。関連:Haswell / Skylakeの部分レジスターはどの程度正確に機能しますか?ALの記述はRAXに誤って依存しているようで、AHは一貫していません