我正在调试一些c ++代码(ARM平台上的WinCE 6), 我发现一些奇怪的行为:
4277220C mov r3, #0x93, 30
42772210 str r3, [sp]
42772214 ldr r3, [pc, #0x69C]
42772218 ldr r2, [pc, #0x694]
4277221C mov r1, #0
42772220 ldr r0, [pc, #0x688]
行42772214 ldr r3, [pc, #0x69C]
用于从.DATA部分获取一些常量,至少我是这么认为的。
奇怪的是,根据代码r2应填充来自地址pc = 0x42772214 + 0x69C = 0x427728B0的内存,但根据从0x427728B8(8字节+)加载的内存内容,它也适用于其他ldr用法。< / p>
是调试器的错误还是我对ldr / pc的理解? 我没有得到的另一个问题 - 为什么访问.data部分是相对于执行的代码?我觉得有点奇怪。
还有一个问题:我找不到第一个mov命令的语法(任何人都可以指出拇指(1C2)的optype规范)
对于laic描述感到抱歉,但我只是熟悉这些程序集。
答案 0 :(得分:17)
这是对的。当pc
用于读取时,ARM模式下有8字节偏移,拇指模式下有4字节偏移。
来自ARM-ARM:
当指令读取PC时,读取的值取决于它来自哪个指令集:
- 对于ARM指令,读取的值是指令的地址加上8个字节。该值的位[1:0]始终为零,因为ARM指令始终是字对齐的。
- 对于Thumb指令,读取的值是指令的地址加上4个字节。该值的位[0]始终为零,因为Thumb指令始终是半字对齐的。
这种读取PC的方式主要用于对附近指令和数据进行快速,位置无关的寻址,包括程序中与位置无关的分支。
pc相对寻址有两个原因。
mov r3, #0x12345678
代替加载它。我不知道ldr r3, [pc, #0x50]
是什么意思。可能是mov r3, #0x93, 30
(给出mov r3, #0x93, rol 30
)?