web-dev-qa-db-ja.com

LEA EAX、[EAX]のポイントは何ですか?

LEA EAX, [EAX]

この命令は、MicrosoftCコンパイラでコンパイルされたバイナリで発生しました。明らかにEAXの値を変更することはできません。では、なぜそこにあるのでしょうか。

43

NOPです。

以下は通常、NOPとして使用されます。それらはすべて同じことをしますが、結果としてマシンコードの長さが異なります。位置合わせの要件に応じて、次のいずれかが選択されます。

xchg eax, eax         = 90
mov eax, eax          = 89 C0 
lea eax, [eax + 0x00] = 8D 40 00 
81
codaddict

this 記事から:

このトリックは、MSVC++コンパイラによって、異なる長さのNOP命令を発行するために使用されます(ジャンプターゲットの前のパディング用)。たとえば、MSVC++は、4バイトと6バイトのパディングが必要な場合に次のコードを生成します。

8d6424 00 lea [ebx + 00]、ebx; 4バイトのパディング8d9b00000000
lea [esp + 00000000]、esp; 6バイトのパディング

最初の行は、コンパイラによって生成されたアセンブリリストで「npad4」とマークされ、2番目の行は「npad6」です。レジスター(ebx、esp)は、コード内の誤った依存関係を回避するために、めったに使用されないレジスターから選択できます。

したがって、これは一種のNOPであり、jmp命令のターゲットを整列させるためにターゲットの直前に表示されます。

興味深いことに、このような命令の特徴的な性質からコンパイラを識別できます。

34
LEA EAX, [EAX]

実際、EAXの値は変わりません。私が理解している限り、機能は次のものと同じです。

MOV EAX, EAX

最適化されたコード、または最適化されていないコードでそれを見ましたか?

3
Eli Bendersky