jal
lyszt.net covers jal and other RISC-V instructions in more detail.
Encoding format
Description
jal calls a function. A function is a named block of instructions that can run from several places and then return, so the logic is written once and used anywhere. Calling a function needs two things. The program jumps to where the function is, and it remembers where it came from to get back afterward. jal does both, and its name is jump and link.
The jump goes to a label that marks the function. The link part happens before the jump. jal saves the address of the next instruction, the one right after the call, into a register. The function uses that saved address to return.
By convention the saved address goes into a register named ra, for return address. The line below jumps to the square function and leaves in ra the address to return to.
jal ra, square
When the function finishes, it returns by jumping to the address in ra, which is what the ret instruction does. The usual shorthand for the same call is shown below.
call square
The RISC-V manual says the jump offset is counted in multiples of 2 bytes, sign-extended and added to the address of the jump instruction. This gives a range of plus or minus 1 MiB, where a MiB is 1,048,576 bytes. jal stores the address of the following instruction, which is pc plus 4, in rd. The standard software calling convention uses x1 as the return address register and x5 as an alternate link register. The unconditional jump instructions use pc-relative addressing, which supports position-independent code, meaning code that works wherever it is loaded in memory.
A jal overwrites ra with a new return address. If a function calls another function, the inner call replaces the saved address of the outer one. A function that makes calls of its own must save ra first and restore it before returning. The example calls square and leaves the return address in ra.
Example
jal ra, square # call square; ra holds the return address
