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. Call-related instructions commonly place the next instruction address in ra, and returns use that address to go back to the caller; 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 Caller
Role
Function return address
Convention
Caller-saved
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 not callee-saved; code that needs it across a call must save it explicitly.

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

ra / x1 is the psABI return-address register. Call sequences commonly place the return address here; it is not preserved across calls, so non-leaf functions must save it 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

  • - Holds the current function's return address, usually written by call / jal / jalr.
  • - Leaf functions often do not need to save ra if they call nobody else.
  • - Non-leaf functions should save ra before calling another function.

When Not To Use It This Way

  • - Do not keep long-lived temporary values in ra.
  • - Do not issue another call before saving ra, or the return address will be overwritten.

What Happens Around A Call

1

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

2

ret usually 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 do non-leaf functions usually save ra?

Because another call writes a new return address and overwrites the old value in ra.