ARM LDR指令以PC为访存基址时地址计算越界问题咨询
问题核心偏差点
你对ARM32指令的PC相对寻址计算逻辑本身没有错:32位ARM状态下硬件采用三级流水线,执行当前指令时PC寄存器值固定为当前指令地址+8,你计算ldr指令取数地址、add指令的PC取值的步骤都是正确的,错在两个基础认知问题:
- 混淆了运行时虚拟内存地址和磁盘文件偏移的概念。你反汇编看到的
0x12de3c0这类地址是程序加载到内存后由操作系统维护的虚拟地址,不是二进制文件在磁盘上的存储偏移。你算出的0x48AA363是内存地址,对应的内容大概率属于rodata(只读数据)段或者其他数据段,ELF格式二进制会把不同属性的段(代码、只读数据、可写数据等)分开映射,段之间在内存中会有对齐空隙,磁盘存储的偏移和内存虚拟地址也不是线性1:1对应的,直接拿虚拟地址去比对磁盘文件大小没有任何意义。 - 误将静态反汇编的占位常量当成运行时有效值。你看到
0x12de7c8位置存储的0x035cbf8f是链接阶段留下的重定位占位符,不是最终计算地址用的真实偏移。如果这个二进制是动态链接的位置无关可执行文件(PIE/PIC),程序加载时动态链接器会根据实际的模块加载基址修正这个位置的值,你用静态占位值算出的地址本来就和运行时真实地址不符。
另外补充一点:反汇编器把0x12de7c8位置的数据解码成cmpeq ip, #572是线性扫描反汇编的正常现象,这个位置是代码段附近的文字池(用来存代码要用到的常量),本来就不是可执行指令,不需要参考这个反汇编结果。
内容的提问来源于stack exchange,提问作者Amin Guermazi
相关产品推荐
相关产品推荐

