【问题标题】:Why is JALR used instead of JAL for returning from subroutines为什么使用 JALR 而不是 JAL 从子程序返回
【发布时间】:2020-05-11 12:48:27
【问题描述】:

我知道jaljalr 都可以用于调用函数,而相反,只有jal 可以用于从这样的函数返回:

sum3:

    add a0, a0, a1
    add a0, a0, a2
    jalr x0, 0(ra)

但是,此代码使用 jal 而不是 jalr 从函数返回并且效果很好:

    call sum3
ret_sum3:   
    # following instructions
    # ...
sum3:

    add a0, a0, a1
    add a0, a0, a2
    jal x0, ret_sum3

有鉴于此,为什么说jalr是函数返回的指令呢?我也可以使用jal

【问题讨论】:

  • call 指令捕获程序计数器 + 4,并将其放入返回地址寄存器 ra - 有效地将其作为参数传递给子程序。子例程使用该值返回给调用者,无论调用者在哪里。因此,调用者不必知道是谁调用的。

标签: assembly riscv


【解决方案1】:

您可能遗漏的一点是,一般来说,一个函数或子例程应该能够从代码中的不同位置调用(即,对子例程的多次调用分布在代码中),所以它应该是也可以返回到代码中的不同位置。

jal 指令跳转到的地址由pc 寄存器的内容加上指令中编码的 21 位常量偏移量决定。因此,使用jal 进行返回的子程序仅限于返回相同的(相对于pc 固定)地址。


jal还能用于子程序返回吗?

如果您的子例程仅从代码中的一个位置调用,它仍然可以使用jal 返回其调用者——只要返回地址对应于大约位于 ±1MB的内存位置> 远离用于返回的jal 指令。如果您想防止ra 寄存器被破坏,只需考虑将子例程调用为jal x0, sum3 而不是call sum3

【讨论】:

    猜你喜欢
    • 2020-02-05
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 2020-03-27
    • 2015-11-02
    相关资源
    最近更新 更多