web-dev-qa-db-ja.com

LEALアセンブリ命令は何をしますか?

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

leal -4(%ebp), %eax       

そして

movl -4(%ebp), %eax

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

21
Serguei Fedorov

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

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

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

43
Adam Rosenfield

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

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 ... <func> 
 [...]

%rdi/%rsiは1st / 2nd 引数を見ると、lea ...が変数のaddress&varを取得するのに対し、mov ...valuevarをロード/保存していることがわかります同じ。

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

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

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

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

結果は次と同じになります:

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

一方、次のとおりです。

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

%eaxの値に5を掛けます。

7
FrankH.

Intel構文のLEAに相当し、実効アドレスをロードします(長い?)。

1
zxcdw

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

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

0
hell