27

の違いについて少し混乱しています

leal -4(%ebp), %eax       

movl -4(%ebp), %eax

誰かが私にこれを説明できますか?

4

4 に答える 4

57

LEA (実効アドレスのロード) は、オペランドのアドレスを計算するだけで、実際に逆参照しません。ほとんどの場合、たとえば配列のインデックス付けなどの乗算と加算を組み合わせたような計算を行っているだけです。

この場合、単純な数値減算を行っています:の値をレジスタにleal -4(%ebp), %eax代入するだけです。これは、宛先がソースの 1 つと同じである必要があることを除いて、単一の命令と同等です。%eax%ebp - 4subsub

対照的に、このmovl命令は のメモリ位置にアクセスし、%ebp - 4その値を に格納します%eax

于 2012-06-26T17:36:35.713 に答える
8

これを別のプログラミング言語の観点から見たい場合は、次のようにします。

int var;
[ ... ]
func (var, &var);

次の (Linux x86_64) アセンブリ コードに評価されます。

[ ... ]
   4: 8b 7c 24 0c mov 0xc(%rsp),%edi
   8: 48 8d 74 24 0c lea 0xc(%rsp),%rsi
   d: e8 xx xx xx xx callq ... <機能>
[ ... ]

%rdi/%rsiは 1番目/ 2番目の引数であるため、変数のアドレスlea ...を取得し、同じをロード/ストアすることがわかります。 &varmov ... var

つまり、アセンブリでは、lea代わりにの使用は、変数自体 (の値) ではなく、C/C++ でmovのアドレス演算子の使用に似ています。&

leaそれよりもはるかに多くの用途がありますが、2つの違いについて明示的に尋ねました.

例として: movwith メモリ オペランドは常にメモリ アクセス (ロードまたはストア) を実行しますが、メモリ オペランド toleaは単にポインタ演算として扱われます。つまり、アドレスは計算および解決されますが、命令自体ではメモリ アクセスは発生しません。この二つ:

lea 1234(%eax, %ebx, 8), %ecx
movl (%ecx), ecx

結果は次のようになります。

movl 1234(%eax, %ebx, 8), %ecx

次の場合:

leal (%eax, %eax, 4), %eax

%eaxを 5 で乗算します。

于 2012-06-28T16:18:33.800 に答える
2

LEAIntel 構文のロード実効アドレス (長い?) と同等です。

于 2012-06-26T17:16:53.720 に答える
-2

LEA と MOV はどちらも、たとえば変数へのオフセットをレジスタにロードできます。

MOV はメモリの内容をレジスタに転送することもできますが、LEA はできません。LEA と MOV の両方で、より効果的な計算を行うために使用できる「実効オフセット」を計算できます。

于 2016-01-15T07:19:03.540 に答える