1

まず最初に、私は ASM の初心者です。これがばかげた質問である場合は、ご容赦ください。

部分的なレジスタ ストールに関するAgner Fog のマイクロアーキテクチャ マニュアルを読みました(これは少し高度なようですが、64 ビット モードの 32 ビット命令がレジスタの上半分をゼロにする理由に興味がありました)。Example 6.13 は、レジスタ ストールを回避する方法を示しています。私はまだこれについて少し混乱しています。なぜ MOV の代わりに OR 操作が使用されなかったのですか?

xor eax, eax
mov al, byte [mem8]
; or  al, byte [mem8] ; why not this?

効果は同じだと思います。どちらも 1 秒あたりのサイクル数は同じですか? 一方は他方よりも効率的ですか?私が他のものよりも好むようになる「ボンネットの下」に何かがありますか?

4

1 に答える 1

2

64 ビット モードでの部分的なレジスタ アクセス

64 ビット モードでは、64 ビット未満のレジスタにアクセスするときに次の規則が適用されます。

  • 32 ビット レジスタにアクセスすると、関連する 64 ビット レジスタの上位 32 ビットがクリアされます。
  • 16 ビットまたは 8 ビット レジスタにアクセスすると、関連する 64 ビット レジスタの上位 48 ビットまたは 56 ビットが残ります。

8 ビット レジスタのみにアクセスする場合は、関連する 64 ビット レジスタの古い値を最初に取得し、8 ビット サブレジスタを変更してから、新しい値を保存する必要があります。

Agner Fog のマイクロアーキテクチャ マニュアルの例 6.13はこれとは関係ありませんmovzx。この命令は古いペンティアム プロセッサでは遅いため、これは の代替にすぎません。

movまたはor

二本の線

31 C0                   xor eax, eax
8A 05 ## ## ## ##       mov al, byte [mem8]

(左側のオペコード) は、2 行目を次のように置き換えた場合よりもおそらく高速です。

0A 05 ## ## ## ##       or  al, byte [mem8]

前の行に依存関係があるため:xor eax, eaxで新しい値が計算された場合にのみ、 eaxに渡すことができますor。さらに、 のバリアントとmov同様に、部分的なレジスタのみがアクセスされるため、速度が低下する場合があります。代わりに、これらの2行を次のように置き換えることをお勧めします

0F B6 05 ## ## ## ##    movzx eax, byte [mem8]

これは、以前のアプローチよりも 1 バイト短く、完全な 32 ビット レジスタにアクセスする命令が 1 つだけです。アグナー・フォグが言ったように

部分的なレジスタ ストールを回避する最も簡単な方法は、常にフル レジスタを使用し、小さいメモリ オペランドから読み取るときにMOVZXorを使用することです。MOVSX

于 2020-07-16T20:03:35.703 に答える