LEA EAX, [EAX]
この命令は、MicrosoftCコンパイラでコンパイルされたバイナリで発生しました。明らかにEAXの値を変更することはできません。では、なぜそこにあるのでしょうか。
NOP
です。
以下は通常、NOP
として使用されます。それらはすべて同じことをしますが、結果としてマシンコードの長さが異なります。位置合わせの要件に応じて、次のいずれかが選択されます。
xchg eax, eax = 90
mov eax, eax = 89 C0
lea eax, [eax + 0x00] = 8D 40 00
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命令のターゲットを整列させるためにターゲットの直前に表示されます。
興味深いことに、このような命令の特徴的な性質からコンパイラを識別できます。
LEA EAX, [EAX]
実際、EAXの値は変わりません。私が理解している限り、機能は次のものと同じです。
MOV EAX, EAX
最適化されたコード、または最適化されていないコードでそれを見ましたか?