[解決済み] x86_64 registers rax/eax/ax/al overwriting full register contents [duplicate] レジスタの内容をすべて上書きする。
質問
広く宣伝されているように、最新の x86_64 プロセッサは 64 ビットのレジスタを持ち、後方互換性を持って、たとえば 32 ビット レジスタ、16 ビット レジスタ、さらには 8 ビット レジスタとして使用することが可能です。
0x1122334455667788
================ rax (64 bits)
======== eax (32 bits)
==== ax (16 bits)
== ah (8 bits)
== al (8 bits)
このようなスキームは文字通りに受け取られるかもしれません。つまり、読み書きの目的で指定された名前を使用しているレジスタの部分だけに常にアクセスすることができ、それは非常に論理的なものでしょう。実際、これは 32 ビットまでのすべてについて当てはまります。
mov eax, 0x11112222 ; eax = 0x11112222
mov ax, 0x3333 ; eax = 0x11113333 (works, only low 16 bits changed)
mov al, 0x44 ; eax = 0x11113344 (works, only low 8 bits changed)
mov ah, 0x55 ; eax = 0x11115544 (works, only high 8 bits changed)
xor ah, ah ; eax = 0x11110044 (works, only high 8 bits cleared)
mov eax, 0x11112222 ; eax = 0x11112222
xor al, al ; eax = 0x11112200 (works, only low 8 bits cleared)
mov eax, 0x11112222 ; eax = 0x11112222
xor ax, ax ; eax = 0x11110000 (works, only low 16 bits cleared)
しかし、64ビットのものになるとすぐにかなり厄介なことになるようです。
mov rax, 0x1111222233334444 ; rax = 0x1111222233334444
mov eax, 0x55556666 ; actual: rax = 0x0000000055556666
; expected: rax = 0x1111222255556666
; upper 32 bits seem to be lost!
mov rax, 0x1111222233334444 ; rax = 0x1111222233334444
mov ax, 0x7777 ; rax = 0x1111222233337777 (works!)
mov rax, 0x1111222233334444 ; rax = 0x1111222233334444
xor eax, eax ; actual: rax = 0x0000000000000000
; expected: rax = 0x1111222200000000
; again, it wiped whole register
このような動作は、私には非常に馬鹿げていて非論理的であるように思えます。それは、まるで
eax
の上位 32 ビットを消去することになります。
rax
レジスタの上位 32 ビットを消去することになります。
では、2点ほど質問させてください。
-
この厄介な動作はどこかに文書化されているはずですが、(64 ビット レジスタの上位 32 ビットが正確にどのようにワイプされるのか)詳細な説明がどこにもないようです。私が正しいのは
eax
に書き込むと常にrax
なのか、それとももっと複雑なものなのか?それはすべての 64 ビット レジスタに適用されるのでしょうか、それともいくつかの例外があるのでしょうか?A に強く関連する質問 は同じ動作に言及していますが、残念ながら、ドキュメントへの正確なリファレンスはまたありません。
言い換えれば、私はこの動作を指定する文書へのリンクが欲しいのです。
-
この全体が本当に奇妙で非論理的であるように思えるのは私だけでしょうか (すなわち、eax-ax-ah-al, rax-ax-ah-al はある動作を持ち、rax-eax は別の動作を持つ)?なぜそのような実装になったのか、私は何か重要なポイントを見逃しているのかもしれません。
なぜなのかについての説明があれば、非常にありがたいです。
どのように解決するのですか?
Intel/AMD プロセッサーのマニュアルに記載されているプロセッサー モデルは、かなり不完全なモデルで 実質的な
の実行エンジンとしてはかなり不完全なモデルです。 特に、プロセッサ レジスタの概念は現実と一致しておらず、EAX または RAX レジスタのようなものは存在しません。命令デコーダーの主な仕事の 1 つは、レガシー x86/x64 命令を マイクロオペレーションズ RISC ライクなプロセッサの命令です。 同時に実行するのが簡単な小さな命令で、複数の実行サブユニットを利用することができます。 同時に6つの命令を実行できる。
それを実現するために、プロセッサのレジスタの概念も仮想化されています。 命令デコーダは、レジスタの大きなバンクからレジスタを割り当てます。 命令が リタイア が終了すると、その動的に割り当てられたレジスタの値は、現在RAXの値を保持しているレジスタに書き戻されます。
この処理をスムーズかつ効率的に行い、多くの命令を同時に実行できるようにするためには、これらの処理に相互依存性がないことが非常に重要です。 そして、最悪のものは、レジスタの値が他の命令に依存することです。 EFLAGSレジスタは悪名高く、多くの命令がこれを変更します。
の方法と同じ問題です。 のように と同じ問題があります。 大きな問題、それは命令がリタイアするときにマージされる2つのレジスタ値を必要とします。 コアを詰まらせることになるデータ依存性を作成します。 上位32ビットを強制的に0にすることで、その依存関係は瞬時に消え、マージする必要がなくなります。 実行速度がワープ9。
関連
-
[解決済み] 32ビットレジスタに対するx86-64命令は、なぜフル64ビットレジスタの上部をゼロにするのですか?
-
[解決済み] Gnuアセンブラ(GAS)のCFIディレクティブは何のためにあるのですか?
-
[解決済み] FS"/"GS "レジスタは何のためにあるのですか?
-
[解決済み] コールスタックはどのように機能するのか?
-
[解決済み] なぜx86は醜いのか?なぜ他と比較して劣っていると言われるのか?[クローズド]
-
[解決済み] 最近のシステムでは、スタックの成長方向はどうなっているのでしょうか?
-
[解決済み] アセンブリコードで "int 0x80 "とはどういう意味ですか?
-
[解決済み] gdbで指定されたアドレスのアセンブリ命令をブレークするには?
-
[解決済み] x86アセンブリの「rep; nop;」とはどういう意味ですか?pause "命令と同じですか?
-
[解決済み] ここでいう「@plt」とは、どういう意味でしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 32ビットレジスタに対するx86-64命令は、なぜフル64ビットレジスタの上部をゼロにするのですか?
-
[解決済み] FS"/"GS "レジスタは何のためにあるのですか?
-
[解決済み] コールスタックはどのように機能するのか?
-
[解決済み] なぜx86は醜いのか?なぜ他と比較して劣っていると言われるのか?[クローズド]
-
[解決済み] 最近のシステムでは、スタックの成長方向はどうなっているのでしょうか?
-
[解決済み] アセンブリコードで "int 0x80 "とはどういう意味ですか?
-
[解決済み] gdbで指定されたアドレスのアセンブリ命令をブレークするには?
-
[解決済み] なぜインテルはプロセッサーに内蔵RISCコアを隠すのか?
-
[解決済み] x86アセンブリの「rep; nop;」とはどういう意味ですか?pause "命令と同じですか?
-
[解決済み] ここでいう「@plt」とは、どういう意味でしょうか?