jal
使用半绝对目标编码(替换PC的低28位),同时bgezal
/ bltzal
是相对的(添加 18 位有符号位移,imm16<<2
). 如何计算跳转目标地址和分支目标地址? https://stackoverflow.com/q/6950230
它们是经典 MIPS 的唯一分支链接(而不是跳转链接),因此对于位置无关的可重定位代码非常重要。(您甚至可以使用一个将当前 PC 放入寄存器并找出您正在执行的位置,这与jal
).
你可以编码bal
(无条件相对函数调用)asbgezal $zero, target
.
你可以得到$ra=PC
与未采取的bltzal $zero, anywhere
无需任何其他设置。这样做与bgezal
需要一个小于零的输入寄存器,需要一个insn来创建。b...al
指示always write $ra
即使分支没有被占用。您希望将其用于与 PC 相关的代码,直到 MIPS32r6 给了我们addiupc
为了更好地生成 PC 相关地址。
由于它们像其他指令一样使用 I 型指令格式b
ranch 指令,一个寄存器的编码中有空间,因此将其设置为可选条件而不是just有一个bal
操作说明。用于执行“与链接”的硬件逻辑已经存在,并且所有其他相关分支指令都是有条件的。另外,有一个不被接受的条件$zero
方便阅读pc
.
请记住,MIPS 指令编码在早期 MIPS 硬件中直接用作内部控制信号,因此它们之间不同的编码中的一位可能会连接到异或门,该异或门反转(或不反转)符号位的检查。 (正如 Konrad 的回答所指出的,这些分支条件仅取决于寄存器的 MSB,因为它始终反对零,因此等待 32 位加法器产生比较结果没有延迟。)
From http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html
0000 01ss sss1 0001 iiii iiii iiii iiii BGEZAL
0000 01ss sss1 0000 iiii iiii iiii iiii BLTZAL
指令编码缺乏灵活性(因为它直接驱动内部控制信号,而不需要在解码中进行大量转换)也许就是为什么不只存在一个指令编码的原因。bal
具有 28 位范围(来自 26 位相对位移)。相关分支的硬件是为具有 16 位立即数的 I 型指令设置的。
TL:DR:有 2 个条件分支链接指令,因为很自然地实现无条件分支链接指令bal
就其中一个而言,另一个几乎是免费的。
MIPS b
(无链接的无条件相对分支)也是一个伪指令beq $zero, $zero, target
,或者由汇编器选择,对于bgez $zero, target
. (无条件分支和无条件跳转(MIPS 中的指令)有什么区别? https://stackoverflow.com/questions/10981593/what-is-the-difference-between-unconditional-branch-and-unconditional-jump-inst/10982754#10982754)。米普斯R3000说明书 https://cgi.cse.unsw.edu.au/~cs3231/doc/R3000.pdf建议beq $zero,$zero
。 (并且更清楚地证明$ra=PC
无论分支如何,都会发生;从我最初撰写此答案时查看的快速参考表来看,这一点并不清楚。)
与零比较编码只有一个 5 位寄存器字段,因此它们消耗的编码空间比beq
/ bne
。这可能是选择的一个原因bgezal
而不是beqal
作为要提供的一对条件分支之一。