如何动态调试来学习ARM汇编 2 r15(PC)寄存器
本帖最后由 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
我们可以看到,PC里保持着下一条将被执行的指令 (mov r0, pc)的地址0xaaad43d8,现在执行mov r0, pc指令之后R0应该是0xaaad43d8吗?
看看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寄存器显示了当前执行指令的地址,当我们真实调试时不要受此影响。
花好s月圆 发表于 2021-3-19 06:23
这用的什么调试工具?不是OD呀。
用的gdb,在安卓上面的远程调试 谢谢老师分享经验,值得学习。 受教受教 谢谢,很好👍👍 厉害啊 有学到了 嘿嘿 学到了,大佬牛啊 学到了,谢谢大佬 好难啊,我还看不明白呢 谢谢老师的分享,我要好好思考,努力学习。 受教了……感谢楼主分享