MIPS 汇编中 J 与 JAL(以及 JR 与 JALR)的必要性

Necessity of J vs. JAL (and JR vs. JALR) in MIPS assembly

我注册是因为我一直在谷歌上搜索这个问题的答案,但找不到。

我想知道在 MIPS 中是否绝对需要不带链接的跳转指令?

我可以想象,例如,在不需要时使用 "AL" 版本会导致一些功率损失,但是是否存在任何情况(这不是完全人为的或可以相对简单地编码)只有 J/JR 有用吗?

谢谢!

Formalizing the comments into an answer


J/JR 可以用 JAL/JALR 模拟,因为后者执行前者操作的超集。

正如@Jester 所指出的,例程(C 术语中的函数)必须小心保存它们在 $ra.
中的 return 地址 除非该例程是叶例程(不进行任何调用的例程),否则 $ra 必须保存在某处。

实际上 JAL/JALRJ/JR 都可以根据另一个来实现:

  • J/JR模拟JAL/JALR

    Original               Emulated
    
    jal foo                la $ra, ret_label
                           j foo
                          ret_label:
    
  • JAL/JALR

    模拟J/JR
    Original                Emulated
    
    j foo                   prolog:
                              addi $sp, $sp, -4
                              sw $ra, ($sp)   
    
                              jal foo
    
                            epilog:
                              lw $ra, ($sp)
                              addi $sp, $sp, 4
    

    为此,代码必须 return 到 epilog。假定 $ra 主要保留在例程中(因此是标签的名称)。 非常感谢@EOF 指出此片段中的错误。

正如@Peter 指出的那样,访问 $pc 可以更轻松地(对人类而言)模拟 JAL/JALR

正如@EOF 指出的那样,一些 RISC 机器实际上只有一条指令用于 JAL/JALRJ/JR 给定它们的先天纠缠。

考虑到跳转和调用在典型程序中经常发生,能够轻松实现(并快速执行)对于任何成功的 ISA 都是必需的。