Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is JALR used instead of JAL for returning from subroutines

Tags:

assembly

riscv

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.

like image 597
Tania Avatar asked Mar 03 '23 21:03

Tania


1 Answers

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.


Can 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.

like image 97
ネロク・ゴ Avatar answered May 06 '23 13:05

ネロク・ゴ