好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 havenow 于 2021-3-18 22:35 编辑
看看PC寄存器(r15)在调试器中的表现形式。
下面的程序,在R0存储PC的地址,并且包含了两条随机的指令。看看究竟会发生什么。
.text
.globl main
main:
mov r0, pc
mov r1, #2
add r2, r1, r1
bx lr
pc1
我们可以看到,PC里保持着下一条将被执行的指令 (mov r0, pc)的地址0xaaad43d8,现在执行mov r0, pc指令之后R0应该是0xaaad43d8吗?
pc2
看看R0中的地址。R0是0xaaad43e0。
下面有两个解释,感觉第二个更靠谱一点:
1、从这个地址我们可以看出,当我们直接读取PC时,它按照定义,PC指向下一条指令,但是当我们调试程序时,PC却指向当前PC值的下面两条指令的地址处(0xaaad43d8+8=0xaaad43e0)。这是因为,老款的ARM处理器总是获取当前已经执行的指令的后两条指令的地址。ARM保留着这个定义的原因是为了保证和早期处理器的兼容性。
2、产生这种差异的原因其实很简单,调试器显示的PC寄存器的值是经过处理的。当0xaaad43d8处的指令被执行时,PC寄存器已经指向了0xaaad43d8+0x8处的指令,这是由于CPU的流水线机制导致的。CPU取指令,解码指令和执行指令时使用的是不同的硬件部件,因此,这几个操作(实际的CPU可能更复杂,有更多的操作步骤)是可以并行执行的。因为RISC CPU的指令长度一定,所以CPU可以在解码指令之前就知道下一条指令的长度,从而在解码指令时取下一条指令,在执行指令时,对下一条指令进行解码,并取下下一条指令,这称为三级流水线。所以ARM当我们在执行0xaaad43d8处的指令时,PC已经指向0xaaad43d8+0x8处进行取指令操作了。这是硬件中真实发生的情况,而调试器为了令展示更有逻辑性,所以PC寄存器显示了当前执行指令的地址,当我们真实调试时不要受此影响。
|
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|