1. ホーム
  2. c

[解決済み] AMD64 -- nopw アセンブリ命令?

2022-02-07 22:34:08

質問内容

このコンパイラの出力で、機械語コード化された nopw 命令は動作します。

00000000004004d0 <main>:
  4004d0:       eb fe                   jmp    4004d0 <main>
  4004d2:       66 66 66 66 66 2e 0f    nopw   %cs:0x0(%rax,%rax,1)
  4004d9:       1f 84 00 00 00 00 00

nopw"については、以下のサイトで議論されています。 http://john.freml.in/amd64-nopl . 4004d2-4004e0 の意味を説明できる人はいますか?オペコードリストを見る限り、どうやら 66 .. のコードはマルチバイト展開です。おそらく、私が数時間にわたってオペコードリストを理解しようとしない限り、ここでこれに対するより良い答えを得ることができるような気がします。


このasmの出力は、C言語の次の(非常識な)コードによるもので、単純な無限ループに最適化されています。

long i = 0;

main() {
    recurse();
}

recurse() {
    i++;
    recurse();
}

でコンパイルした場合 gcc -O2 このため、コンパイラは無限再帰を認識し、無限ループに変換します。 main() を呼び出すことなく recurse() 関数を使用します。


編集部注:NOPsで関数を水増しするのは、無限ループに限ったことではありません。 以下は、NOPの長さの幅がある関数のセットです。 をGodboltコンパイラエクスプローラーに追加しました。

解決方法は?

その 0x66 バイトは "Operand-Size Override" の接頭辞です。これを複数個持つことは、1個持つことと同じです。

は、その 0x2e は、64 ビットモードでは「ヌル接頭辞」です(それ以外の場合は CS: セグメントのオーバーライドであり、アセンブリ ニーモニックに表示されるのはそのためです)。

0x0f 0x1f はModRMバイトを受け取るNOPの2バイトオペコードです

0x84 ModRMバイト この場合、さらに5バイトを使用するアドレス指定モードを意味します。

CPUによっては、プレフィックスが多い(例えば3つ以上)命令のデコードが遅いので、SIB + disp32を指定するModRMバイトは、プレフィックスバイトを5つ増やすよりも、5バイト余分に使い切る方がはるかに良い方法です。

<ブロッククオート

Agner FogのmicroarchにあるAMD K8デコーダーのpdf :

各命令デコーダは、1クロックあたり3つのプリフィックスを処理することができます。 サイクルです。つまり、3つのプリフィックスを持つ3つの命令が、それぞれ 同じクロックサイクルでデコードされます。4〜6個のプリフィックスを持つ命令 は、デコードに余分なクロックサイクルを必要とします。


基本的に、これらのバイトは1つの長いNOP命令であり、いずれにせよ実行されることはないでしょう。 これは、次の関数が16バイト境界にアラインされていることを確認するためのもので、コンパイラが .p2align 4 ディレクティブがあるため、アセンブラはNOPで水増ししています。 gcc の x86 用のデフォルトは
-falign-functions=16
. 実行されるNOPの場合、long-NOPの最適な選択はマイクロアーキテクチャに依存します。 Intel Silvermont や AMD K8 のように、多くのプリフィックスで詰まるマイクロアーキテクチャの場合、3 つのプリフィックスを持つ 2 つの NOP の方が速くデコードできたかもしれません。

質問のリンク先のブログ記事( http://john.freml.in/amd64-nopl ) は、コンパイラが1バイトの0x90 NOP命令の束ではなく、複雑な1つのNOP命令を使用する理由を説明しています。

命令のエンコードに関する詳細は、AMDのtech refドキュメントに記載されています。

主に「"AMD64 Architecture Programmer's Manual Volume 3: General Purpose and System Instructions"」に記載されています。 Intelのx64アーキテクチャの技術資料にも同じ情報が載っているはずです(もっと分かりやすいかもしれません)。