我正在调试一些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 (8bytes+)加载的内存内容,其他ldr使用也会发生这种情况。
是调试器的问题还是我对ldr/pc的理解?我不明白的另一个问题是,为什么对.data部分的访问是相对于执行的代码而言的?我觉得这有点奇怪。
还有一个问题:我找不到第一个mov命令的语法(任何人都可以为我指出拇指的optype规范(1C2))
很抱歉给你这么粗俗的描述,但我只是在熟悉这些程序集。
发布于 2010-01-21 00:24:31
这是正确的。使用pc读取时,ARM模式下有8字节偏移量,拇指模式下有4字节偏移量。
从手臂-手臂:
当指令读取PC时,读取的值取决于它来自哪个指令集:
这种读取PC的方式主要用于快速、位置独立地寻址附近的指令和数据,包括程序内的位置独立分支。
使用pc相对寻址有两个原因。
mov r3, #0x12345678不可能在一条指令中完成,所以编译器可能会把这个常量放在函数的末尾,并使用例如ldr r3, [pc, #0x50]来加载它。我不知道mov r3, #0x93, 30是什么意思。可能是mov r3, #0x93, rol 30 (它提供了0xC0000024)?
https://stackoverflow.com/questions/2102921
复制相似问题