为什么ARM PC寄存器指向下一个要执行的指令后?

new*_*bie 33 assembly arm

根据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年它很酷.

*"......地球上NOP最多的指令集."

  • @newbie这不是PC的lsb - 会导致对齐错误 - 它只是控制指令集切换的`bx`,`blx`或`bxj`指令的_target address_的lsb.当前状态在CPSR的第5位中指示. (4认同)
  • 喜欢你的回答!请问您对于使用PC寄存器的最低有效位来确定CPU状态有何看法?这不是很奇怪吗? (2认同)
  • 我想知道ARM设计者有多少次诅咒必须保持CPU与旧的行为兼容.而且,与延迟槽一样糟糕,关于它们的最糟糕的事情是它们的记录是多么糟糕,尤其是汇编程序如何处理它们(汇编程序经常试图隐藏它们的存在,这似乎是最糟糕/最混乱的事情)在我看来). (2认同)