add
コマンドが使用されているARMアセンブリのスニペットに焦点を当てています。以下のスニペットは、単純に次のように述べています。 プログラム カウンタのアドレスに、 に格納されている文字列の位置を見つけるために計算されたオフセットを追加しL._str
ますL._str
。
movw r0, :lower16:(L_.str-(LPC1_0+4))
movt r0, :upper16:(L_.str-(LPC1_0+4))
LPC1_0:
add r0, pc
最初の 2 つの命令 (movw
およびmovt
) は、その文字列のアドレスを表す 32 ビットの数値をロードします。私は親指モードですよね?わかりました、そう言ったので、全体的なメモリ レイアウトを把握する方法がわかりません。以下は、メモリのコード セグメントの正しい表現ですか? またLPC1_0
、L._str
ベースアドレスは文字列add r0, pc
のアドレスですか?A simple string
各箱の寸法は?アーキテクチャに応じて 32 ビットまたは 64 ビット。
--------------------------------------------
| movw r0, :lower16:(L_.str-(LPC1_0+4)) |
--------------------------------------------
| movt r0, :upper16:(L_.str-(LPC1_0+4)) |
-------------------------------------------- LPC1_0
| add r0, pc |
--------------------------------------------
.
.
.
-------------------------------------------- L._str
| "A simple string" |
--------------------------------------------
pc
もしそうなら、差分を使用してオフセット (に追加される) を取得できますL_.str-LPC1_0
。しかし、ここ+4
でも考慮されます。
ADD Rd、Rp、#expr
Rp が pc の場合、使用される値は (現在の命令のアドレス + 4) AND &FFFFFFFC です。
そのため、オフセット オフセットのバイト数も考慮する必要があるようpc
です。Ok。それで、これらのバイトはどこに追加されますか?これらの 4 バイトが、コマンドの前ではなく、命令で考慮されるのはなぜですか? これはコンパイラによって導入された最適化機能ですか?Rp
+4
mov
add