ARM寄存器R15存放偏移量计算的问题

程序计数器PC(R15):由于ARM采用流水线机制,PC值为当前指令地址值加8字节,ARM指令集中,PC指向当前指令的下两条指令的地址,由于ARM指令是字对齐的,PC值的bit0位和bit1位的值总为0,即PC值为4的倍数。

     当使用STR/STM指令保存R15时,保存的可能是当前指令地址加8字节或12字节,具体采用哪种方式取决于具体的芯片设计方式。同一芯片只能采用一种方式,如下代码可测试出芯片采用的地址偏移量:

      SUB R1, PC, #4            ;R1中存放下面STR指令的地址
      STR PC, [R0]                ;将PC=STR地址+offset保存到R0中
      LDR R0, [R0]                ;
      SUB R0, R0, R1            ;将offset=PC-STR地址保存到R0中  

在这个问题中,8字节和12字节是根据什么决定的?

 

解答:

1.

我是这么理解的,假设是顺序执行,没有跳转分支,本来pc的值是等于当前执行指令地址+8字节的地址,即指向当前指令的下2条指令地址。但是当使用STR/STM这个命令将PC的值保存到RAM或其他寄存器时,这个过程的实现在不同的芯片上有不同的设计,有的芯片实现这个功能时保留了原来的偏移量,即8个字节,但是有的芯片设计时出于某种结构上或性能上或其他方面的考虑,将原来的8个字节不得不改成了12个字节。所以导致了在使用STR/STM保存PC的值时出现了两种不同的偏移量。
我开始是将使用STR/STM保存时的偏移量与PC自己的偏移量弄混了。

2.

     SUB R1, PC, #4            ;R1中存放下面STR指令的地址
      STR PC, [R0]                ;将PC=STR地址+offset保存到R0中
      LDR R0, [R0]                ;
      SUB R0, R0, R1            ;将offset=PC-STR地址保存到R0中  

由此来说,测试使用STR/STM的偏移量的过程应该是这样的:
(1)首先将PC的值减4,即执行SUB R1,PC,#4时,PC应该指向当前地址的下2条地址,也就是指向了LDR R0,[R0],但是PC-4后就指向了STR PC,[R0]这个地址;
(2)将PC中的地址值,使用STR这个命令保存到R0寄存器中存放的那个值指向的地址中去,注意,此时的保存起来的这个值就是不确定的那个值,要么是当前的PC值+8,要么是当前的PC+12,谁让使用了STR了呢。
(3)将这个值取回放进R0寄存器里,为了下一步的减法计算用;
(4)用R0中的值减去R1中的值就是那个不确定的偏移量的值,然后再给他保存在R0中,谁爱用谁去用。

 

ARM寄存器R15存放偏移量计算的问题

上一篇:National Treasures HDU - 3360


下一篇:Logback