Assembly 将程序计数器添加到目标寄存器(Rd)的点

Assembly 将程序计数器添加到目标寄存器(Rd)的点,assembly,arm,Assembly,Arm,我已经用IDA演示反汇编了一个.so文件(ELF文件),我被这条指令卡住了 ADD R4, PC ; _GLOBAL_OFFSET_TABLE_ 这是什么意思?我知道PC是一个保存下一个指令地址的变量,但将它添加到R4的目的是什么 提前谢谢 更新: PUSH.W {R4 - R11, LR} LDR R4, =(_GLOBAL_OFFSET_TABLE_ - 0x11FACC) LDR.W R11, =0x4D4 MOV R9, R3 ADD R4, PC SUB SP, SP, #0x34

我已经用IDA演示反汇编了一个.so文件(ELF文件),我被这条指令卡住了

ADD R4, PC ; _GLOBAL_OFFSET_TABLE_
这是什么意思?我知道PC是一个保存下一个指令地址的变量,但将它添加到R4的目的是什么

提前谢谢

更新:

PUSH.W {R4 - R11, LR}
LDR R4, =(_GLOBAL_OFFSET_TABLE_ - 0x11FACC)
LDR.W R11, =0x4D4
MOV R9, R3
ADD R4, PC
SUB SP, SP, #0x34
ADD R7, SP, #0xC
MOV.W R8, 0

其思想是位置无关的代码

加载模块时,它会获得任意基址。所有全局对象(即变量和函数)驻留在某些虚拟地址;在构建时,您不知道这些地址是什么。但是链接器知道它们之间的相对偏移量;这些在加载时不会改变


因此,为了避免重新定位,从而加快模块加载,并且出于其他有益的原因,正在生成位置无关的代码。在您的示例中,R4最初包含当前PC和某些感兴趣的全局对象之间的地址差异。所说的差异是一个链接时间常数-它是由链接器计算的,永远不会改变。通过将PC添加到所述差异中,代码获得该全局对象的绝对地址。它是什么-通过检查R4接下来会发生什么,您可以知道;无论是取消引用还是分支到。

这是针对位置无关代码()完成的。

从全局偏移表加载值。此值是代码中两个位置之间的差值。然后将电脑添加为基座,以获取您想要访问的实际位置

这主要针对库,因为这样不同的程序可以将库映射到不同的地址空间


如果没有PIC,库必须根据每个程序加载到的基址重新定位。这将允许共享实际内存页。

您有更多的上下文(相邻的说明)吗?@Michale我编辑了帖子并添加了附近的说明。希望它能帮助你更清楚地理解我的问题。谢谢。这种想法不仅仅是位置独立的代码;它是每个用户或实例加上单独的/私有的数据部分。共享库的多个用户的代码页相同,但每个用户的全局数据不同。(塞瓦用不同的语言说了些什么)。
LDR R4, =(_GLOBAL_OFFSET_TABLE_ - 0x11FACC)