根据ARM IC.
在ARM状态下,PC的值是当前指令的地址加上8个字节.
在Thumb状态:
- 对于B,BL,CBNZ和CBZ指令,PC的值是当前指令的地址加上4个字节.
- 对于使用标签的所有其他指令,PC的值是当前指令的地址加上4个字节,结果的位[1]清零以使其字对齐.
简单地说,PC寄存器的值指向下一条指令后的指令.这是我没有得到的.通常(特别是在x86上)程序计数器寄存器用于指向要执行的下一条指令的地址.
那么,底层的前提是什么?有条件执行,也许?
Not*_*hat 52
这是一个令人讨厌的遗留抽象泄漏.
最初的ARM设计有一个3级流水线(fetch-decode-execute).为了简化设计,他们选择将PC读取为当前指令获取地址线上的值,而不是2个周期前当前正在执行的指令的值.由于大多数PC相关地址是在链接时计算的,因此装配器/链接器补偿该2指令偏移比设计所有逻辑以"校正"PC寄存器更容易.
当然,这完全是坚持"30年前有意义的事情".现在想象一下如何在今天的15个阶段,多个问题,无序管道中保持一个有意义的价值,你可能会理解为什么现在很难找到一个CPU设计师,他们认为将PC暴露在寄存器是个好主意.
不过,在好的方面,至少它并不像延迟时段那么可怕.相反,与您的假设相反,让每条指令有条件地执行实际上只是围绕该预取偏移的另一种优化.在分支条件代码(或者仍然像管道疯狂的人一样执行管道中的任何内容)时,不必总是必须采取管道刷新延迟,而是可以完全避免非常短的分支; 管道保持忙碌和解码指令可以只作为NOP执行时,标志不匹配*.同样,这些天我们有了有效的分支预测器,它最终成为一个障碍而不是一个帮助,但1985年它很酷.