質問: アセンブラについて学習しているのですが下記のような命令が出てきます。 これはどういう処理なのでしょうか? leaがアドレスの値(内容ではない)をレジスタに書き込む命令であることはわかります。 最初の(%rdi,%rcx,1)の部分でなぜこれでレジスタを指定できるのかがわかりません。 OS: Linux Arch: x64(amd64) ``` lea (%rdi,%rcx,1),%eax ```
回答: (%rdi,%rcx,1) がレジスタを指定しているのではなく、lea という命令そのものが、 計算値(または即値)と、その結果をどこに格納するか、を指定するものなのです。 (アドレス計算と書かれていますが、必ずしもそれに特化しているわけでは無いです。) だから、それぞれが指定された計算方法/値(レジスタと即値を使ってアドレス計算する)と、 指定された格納先(レジスタ)、となります。 これらは32bitの説明ですが。 LEA命令(Load Effective Address) アドレス計算命令 > > 注意 LEA 命令は、src オペランドを mov 命令と同じように計算する。しかし、そのアドレスの中身を dest オペランドにロードするのではない。アドレスそのものをロードするのである。 > > > lea は、アドレスを計算するのだけに使用されるのではなく、一般的な符号なしの整数の算術計算にも使用される。注意事項として、フラグが変更されないという利点がある。 これは本当にパワフルである。というのも、srcオペランドは最大 4 つのパラメーターを取ることができるからである。つまり、ディスプレイスメント、ベースレジスター、オフセットレジスター、スカラ乗算器である。 例えば、[eax - 4 + edx * 4] (Intel 構文)、-4(%eax, %edx, 4) (GAS 構文) のようにである。 > > > Linuxというからこちらの方が相応しいですか。 Linux で64bitアセンブリプログラミング (07) > > 実効アドレスをレジスタに設定します。MOV命令では指定メモリアドレス(実効アドレス)の内容をレジスタに転送しますが、LEAはメモリの内容ではなくアドレスの値そのものをレジスタに設定します。 アドレッシングモードで説明した SIB を利用すると演算に利用できます。実効アドレスのビット数よりレジスタが小さい場合は上位ビットがレジスタの長さまで切り捨てられます。 > > > こちらは紹介するに相応しいか疑問ですが、本家S.O.の記事で色々議論されているようなので。 What's the purpose of the LEA instruction?