ARM pc寄存器并不总是当前指令的地址加4(Thumb状态)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARM pc寄存器并不总是当前指令的地址加4(Thumb状态)相关的知识,希望对你有一定的参考价值。

根据ARM IC。

在Thumb状态:

  • 对于B,BL,CBNZ和CBZ指令,PC的值是当前指令的地址加上4个字节。
  • 对于使用标签的所有其他指令,PC的值是当前指令的地址加上4个字节。

在调试程序时,我发现pc并不总是当前指令的地址加上4个字节,例如,下面的指令(2)。 有人能解释一下吗?谢谢。

0x2a003118  ldr r3, [pc, #120]  ; (0x2a003194 <main()+684>)   <---(1)
0x2a00311a  ldr r3, [r4, r3] 
0x2a00311c  mov r0, r3 
0x2a00311e  ldr r3, [pc, #136]  ; (0x2a0031a8 <main()+704>)   <---(2)
0x2a003120  add r3, pc                                        <---(3)
0x2a003122  mov r1, r3 
0x2a003124  bl 0x2a00338c
0x2a003128  mov r3, r0 
0x2a00312a  mov r0, r3 
0x2a00312c  ldr r3, [pc, #108]  ; (0x2a00319c <main()+692>)   <---(4)

============================================================

(1).ldr r3, [pc, #120] ; (0x2a003194 <main()+684>)
    p/x $pc+4+120 
    $1 = 0x2a003194
   ; $pc+4 ,Correct

(2).ldr r3, [pc, #136] ; (0x2a0031a8 <main()+704>) 
    p/x $pc+4+136 
    $2 = 0x2a0031aa
   ; Wrong! it should be 0x2a0031a8($pc+2) instead of 0x2a0031aa($pc+4).

(3).add r3, pc
    p/x $r3+$pc+4  
    $3 = 0x2a025c04
   ; $pc+4 ,Correct

(4).ldr r3, [pc, #108]  ; (0x2a00319c <main()+692>)
    p/x $pc+4+108 
    $4 = 0x2a00319c
   ; $pc+4 ,Correct
答案

在ARM DDI 0487B.a中

T32对PC使用的限制,以及使用0b1111作为寄存器说明符在T32指令中通常不允许使用0b1111作为寄存器说明符。当允许值0b1111时,可以有多种含义。对于寄存器读取,这些含义包括:

  • 读取PC值,即当前指令的地址+ 4.表分支指令TBB和TBH的基址寄存器可以是PC。这意味着分支表可以在指令之后立即放入存储器中。

注 - ARM不建议将PC用作STC指令中的基址寄存器。

  • 读取字对齐的PC值,即当前指令的地址+4,位[1:0]强制为零。 LDC,LDR,LDRB,LDRD(预索引,无写回),LDRH,LDRSB和LDRSH指令的基址寄存器可以是字对齐的PC。这提供了PC相关数据寻址。此外,ADD和SUB指令的某些编码允许其源寄存器为0b1111用于相同目的。

你应该在你的参考中寻找类似的东西。

以上是关于ARM pc寄存器并不总是当前指令的地址加4(Thumb状态)的主要内容,如果未能解决你的问题,请参考以下文章

ARM MOV PC加8

为啥ARM PC寄存器指向下一条要执行的指令之后?

ARM PC寄存器

ARM指令中PC指针取址问题

ARM 架构

ARM指令adr adrl ldr mov