例程必须在发出的分支指令的 128 或 -127 字节内的硬件原因是什么?
2 回答
硬件原因有两个:
首先,6502 是一个 8 位处理器,这意味着单个字节可以保存从 0 到 255 的无符号值,或者如果第 7 位用于指示符号(二进制补码),则为 -128 到 +127。
其次,Chuck Peddle 将分支指令设计为双字节操作 - 第一个字节表示分支条件(操作码),第二个字节表示条件为真时要添加到程序计数器 [PC] 的有符号偏移值(操作数) .
现在很明显,使用单个带符号偏移字节作为分支操作数意味着BRx
指令可以容纳的最大“跳转”范围是从当前 PC 向后移动 128 个位置,或者向前移动 127 个位置。
如果您需要超出范围允许的分支(而不是jump ,请参见下文),则要克服此限制可能会很麻烦;但是,在 6502 汇编编程技术方面的实践和经验以及对代码流程和组织的深刻理解通常会允许进行巧妙的设计,从而避免需要进行更远的分支。
CPU 架构通过具有令人难以置信的快速指令来补偿范围限制BRx
- 如果不采用分支,则只有 2 个周期,如果是,则只需多一个周期(即读取操作码和操作数并设置比较内部寄存器中的掩码,如果条件为真,则再将操作数添加到 PC)。
相比之下,该JMP
指令允许程序流跳转到 16 位地址范围内的任何位置,因为它使用两个字节的地址操作数 - 但表现出平坦的 3 周期成本并且是无条件的。使用分支和由分支索引的跳转表或自修改代码的仔细构造JMP
允许程序员利用速度和条件,BRx
并且仅在条件为真时才产生“远跳转”成本。
这是因为条件分支语句只有 2 个字节长,第一个字节是指令的操作码,第二个字节是有符号(二进制补码)值,如果条件为真,则标记到要分支到的地址的距离。(我相信值是 DestinationAddress - AddressImmediatelyFollowingBranchStatement)。使用二进制补码且只有一个字节可用,到目标地址的距离限制在以下范围内:[-128, +127]。
简而言之,这是因为 6502 的设计者只提供了二进制补码中的单个有符号字节作为条件分支语句的参数。