Register Guide

RISC-V ra / x1 Register: Return Address, Calls, and Save Responsibility

ra is the return-address register in the RISC-V calling convention. JAL or JALR writes the next instruction address to ra when x1 is its destination; the ret pseudoinstruction returns through that address. The psABI marks ra as not preserved across calls.

psABI: x1 is named ra and means Return address.
ISA: the standard calling convention uses x1 for the call return address.
Beginner rule: if you will call another function, do not assume the old ra survives automatically.
Physical Name x1ABI Name raSave Rule Not preserved across calls
Role
Function return address
Convention
Not preserved across calls
Remember This First
jal / jalr write the next instruction address into ra unless rd is something else.
psABI Reference

Return address register

The psABI names x1 as ra for the return address. It is marked not preserved across calls; code must explicitly save a value that needs to survive a call.

Preserved across calls: No
RISC-V psABI integer register convention
Quick Understanding & Search Notes

ra / x1 is the psABI return-address register. A call sequence that uses x1 as its link destination writes the next instruction address here; it is not preserved across calls, so a value that must survive a call must be saved explicitly.

The psABI names x1 as ra, meaning return address.
ra is not preserved across calls; save it before nested calls when the old return address is still needed.

When It Fits Best

  • - When JAL or JALR uses ra/x1 as rd, ra holds the next instruction address.
  • - Explicitly save ra before a call when its value must survive that call.
  • - ret is the assembler pseudoinstruction that returns through ra/x1.

When Not To Use It This Way

  • - Do not keep long-lived temporary values in ra.
  • - When a call uses ra/x1 as its link destination and the old value is still needed, save ra first.

What Happens Around A Call

1

jal / jalr write the next instruction address into ra unless rd is something else.

2

ret expands to jalr x0, 0(ra), so it depends on the address stored in ra.

3

If the function calls others, saving and restoring ra becomes this function's own responsibility.

Protect ra In A Non-Leaf RV64 Function

Examples explain the rule, not a complete program
addi sp, sp, -16
sd   ra, 8(sp)
call foo       # ra is overwritten; use sw/lw for 32-bit RV32 saves
ld   ra, 8(sp)
addi sp, sp, 16
ret

FAQ

Is ra / x1 automatically preserved across calls?

No. The psABI marks ra as not preserved across calls; save it explicitly when it must survive a call.

Why does another call that uses ra overwrite its old value?

Because a JAL or JALR that uses ra/x1 as its link destination writes a new next-instruction address and overwrites the old value.