jal
jal
rd, label
rd = pc + 4; goto label
R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

jal is how you call a function. A function is a named block of instructions you can run from several places and then return from — write the logic once, use it anywhere. Calling one means two things must happen: jump to where the function lives, and somehow remember where you came from so you can get back afterward. jal does both at once, which is why its name is jump and link.

The jump part goes to a label marking the function. The link part is the clever bit: just before jumping, jal saves the address of the *next* instruction — the spot right after the call — into a register. That saved address is the breadcrumb the function will follow home.

By convention that breadcrumb goes into a register named ra, for return address. So jal ra, square jumps to the square function and leaves in ra the address to come back to. When the function finishes, it returns by jumping to whatever ra holds (the ret instruction does this). Writing call square is the usual shorthand for the same thing.

One warning that defines correct function code: each jal overwrites ra with a new return address. If a function calls another function, that inner call replaces the outer one's saved address — so a function that makes calls of its own must first save ra somewhere safe and restore it before returning. The example calls square, leaving the return address in ra.

jal ra, square   # call square; ra holds the return address