このLEAL命令に関する0x10の機能は何ですか?それは乗算または加算ですか?
leal 0x10(%ebx), %eax
誰かが明確にできますか?これは、Linuxボックス上のx86アセンブラーです。
leal、またはleaのフルネームは「実効アドレスのロード」であり、まさにこれを行います。アドレス計算を行います。
この例では、アドレスの計算は非常に簡単です。これは、ebxにオフセットを追加し、結果をeaxに格納するだけだからです。
eax = ebx + 0x10
leaはもっと多くのことができます。レジスタを追加したり、ワード、整数、倍精度のアドレス計算用に定数2、4、8でレジスタを乗算したりできます。オフセットを追加することもできます。
Leaは、上記の例のように単純な追加として使用する場合でも、フラグを変更しないという点で特別であることに注意してください。コンパイラはこの機能を悪用し、スケジューラを支援するために追加機能をリーに置き換えることがあります。そのため、コンパイル済みコードで簡単な算術演算を行うlea命令を見るのは珍しいことではありません。
lea
は「ロード実効アドレス」を表します。これは、IA32命令セットの洗練されたアドレス指定モードを使用して算術を行う方法です。 l
接尾辞は、LinuxボックスにあるGNU asの構文で命令オペランドのサイズを区別する方法です。
要するに、はい、それは一種の加算命令です。また、2、4、または8による乗算を同時に処理できます。
この関連する質問 も参照してください(Intel構文を使用して同じ命令を議論している場合)。
GNU as 2.18 docs
https://sourceware.org/binutils/docs-2.18/as/i386_002dMemory.html
AT&T:-4(%ebp)、Intel:[ebp-4]
そして、Intel構文は自明です。
さらに重要なこととして、ドキュメントでは一般的なケースについても説明しています。
次の形式のIntel構文間接メモリ参照
_ section:[base + index*scale + disp]
_
aT&T構文に変換されます
_ section:disp(base, index, scale)
_
baseおよびindexはオプションの32ビットのベースおよびインデックスレジスタ、dispはオプションの変位、およびスケールです。値1、2、4、および8を取り、インデックスを乗算してオペランドのアドレスを計算します
アドレスの一部を省略すると、AT&Tでは物事が少し面倒になります。 -4(%ebp)
ですが、ドキュメントの例により、すべての構文のケースを簡単に推測できます。
何が起こっているのかを本当に理解するために、命令がどのようにエンコードされているかを調べることをお勧めします。これは良いチュートリアルです: http://www.c-jump.com/CIS77/CPU/x86/lecture.html それを見れば、なぜいくつかのアドレスの一部、および各フォームのコンパイル先を省略できます。
Nilsの応答に追加するには、
復習として、IA32アセンブラーのアドレス設定モードは一般に次の形式です。
IO(Rb、Ri、s)、ここで:
IO =即時オフセット
Rb =ベースレジスタ
Ri =インデックスレジスタ
s =スケーリング係数{1、2、4、8}
したがって、実効アドレスは* IO + [Eb] + [Ei]sとして計算されます
lealはmovlのような他の命令に似ていますが、少し特別です。ソースから宛先に読み取る代わりに、ソースの実効アドレスを宛先にコピーします。
したがって、Nilsが指摘したように、後のメモリ参照用のポインターを生成したり、基本的な算術演算に使用したりできます。
例えば:
レジスタ%edxにxの値が含まれるようにします
leal 1(%edx、%edx、8)、%eax
%eaxを登録するために、1 + x + 8 * x = 1 + 9xの実効アドレスをロードします。
本質的に、操作:
lealsource、destination=>destination= のアドレスsource
Cに精通している場合、次と同等です。
char * b =&a;
ここで、char aのアドレスはcharポインターbに割り当てられます
その他の例:
レジスタ%eaxが値xを保持し、レジスタ%ecxが値yを保持するようにします
leal(%eax、%ecx、4)、%edxは値x + 4yをレジスタ%edxに割り当てます
leal 0xB(、%ecx、5)、%edxは値0xB + 5y = 11 + 5yを%edxに割り当てます
leal(%eax、%eax、2)、%eaxは値3xをレジスタ%eaxに割り当てます
お役に立てれば