I´ve learned that both jal
and jalr
can be used for calling functions while on the contrary only jal
can be used for returning from functions like this:
sum3:
add a0, a0, a1
add a0, a0, a2
jalr x0, 0(ra)
However, this code uses jal
instead of jalr
for returning from a function and it works well:
call sum3
ret_sum3:
# following instructions
# ...
sum3:
add a0, a0, a1
add a0, a0, a2
jal x0, ret_sum3
In view of this, why it is said that jalr
is the instruction for returning from a function? I can use jal
for that too.
The point that you may be missing is that, in general, a function or subroutine should be able to be called from different places in the code (i.e., multiple calls to the subroutine spread across the code), so it should be able to return to different locations in the code as well.
The address the jal
instruction jumps to is determined by the contents of the pc
register plus a 21-bit constant offset that is encoded in the instruction. Therefore, a subroutine that uses jal
for returning is limited to return to the same (fixed relative to pc
) address.
jal
still be used for subroutine return?If your subroutine is only called from a single location in the code, it can still use jal
for returning to its caller – provided the return address corresponds to a memory position located at roughly ±1MB away from the jal
instruction used for returning. Just consider calling the subroutine as jal x0, sum3
instead of call sum3
if you want to prevent the ra
register from being clobbered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With