为什么程序必须在发出分支指令的128或-127字节范围内执行?这是由硬件限制所决定的。
硬件原因有两个:
首先,6502是一种8位处理器,这意味着单个字节可以保存从0到255的无符号值,或者如果使用第7位来表示符号(二进制补码)则为-128至+127。
其次,Chuck Peddle将分支指令设计为一个双字节操作——第一个字节表示分支条件(操作码),第二个字节表示有符号偏移值(操作数),如果条件成立,则将其添加到程序计数器[PC]中。
如今已经显而易见,使用单个有符号偏移字节作为分支操作数意味着BRx
指令可以容纳的最大“跳跃”范围要么向当前PC后退128个位置,要么向前跳127个位置。
在需要分支距离超过范围的情况下,这种限制可能会很麻烦;然而,对6502汇编编程技术进行实践和经验,深入了解代码流程和组织常常可以通过巧妙的设计避免需要跨越更大的距离。
CPU体系结构绝对能够弥补范围限制,因为BRx
是一条非常快的指令——如果分支不被执行,只需要2个时钟周期;如果执行,则只需再加上一个时钟周期(即2个时钟周期读取操作码和操作数,并在内部寄存器中设置比较掩码,然后再添加操作数到PC,如果条件成立)。
相比之下,JMP
指令允许程序流在16位地址范围内跳转到任何位置,因为它使用双字节地址操作数,但是它的开销是固定的3个周期,并且无条件执行。通过精心构建跳转表或使用JMP
自修改代码并由分支索引来利用BRx
的速度和条件性,程序员可以只在条件成立时才产生“远跳转”的开销。
BEQ label
转换为BNE 3; JMP label
,如果label
不适合于有符号8位范围。 - Cactus