我专注于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
前两条指令 (movw
和movt
) 加载表示该字符串地址的 32 位数字。我在拇指模式,对吧?好的,这么说,我很难弄清楚整体内存布局。以下是内存代码段的正确表示吗?另外,字符串的地址是LPC1_0
和L._str
基地址吗?每个盒子的尺寸是多少?32 位或 64 位取决于架构。add r0, pc
A simple string
--------------------------------------------
| 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
也考虑到了。
添加 Rd,Rp,#expr
如果 Rp 是 pc,则使用的值是:(当前指令的地址 + 4)AND &FFFFFFFC。
因此,如果pc
是的话,Rp
我似乎还需要考虑+4
偏移量的更多字节。行。那么,这些字节是在哪里添加的呢?为什么将这 4 个字节考虑在mov
指令中而不是在add
命令之前?这是编译器引入的优化功能吗?