RISC-V Assembler Function/Stack

How Assembly Functions Work - The Stack Explained (YouTube)

RISC-V Assembler: Jump and Function

confusion about function call stack

RISC-V assembly - stack layout - function call

Calling Functions in Assembly

1.1. RV32I Base Integer Instruction Set, Version 2.1

Stack Frame

Functions need to keep track of its local variables. Local variables go in stack frames on the call stack. When a function is called it moves the stack pointer down making room for the function's local variables. When it returns it moves the stack pointer up.

A register is used to keep track of the address of the current stack frame. According to the RISC-V calling convention, register sp (x2) contains the address of the bottom (the smallest address) of the current stack frame.

Code interacts with sp in three ways:

In this example addi at the beginning and end of a function "creates" and "destroys" a stack frame of 8 bytes.

func_label: addi sp, sp, -8 ... ... ... addi sp, sp, 8 ret

Code from HERE

Print a String

Using the Standard Linux System Call (sys_write)

If you are compiling your assembly code directly on a RISC-V Linux machine or executing via QEMU, you must utilize standard Linux ABI system calls.

Printing a String (sys_write)... .data msg: .ascii "Hello via Linux!\n" len = . - msg # Calculate length of the string dynamically .text .global _start _start: li a7, 64 # Linux sys_write system call number li a0, 1 # File descriptor: 1 is stdout la a1, msg # Pointer to the string li a2, len # Length of the string ecall # Invoke system call # Graceful exit (sys_exit) li a7, 93 # Linux sys_exit system call number li a0, 0 # Exit status code 0 ecall

Note: If your environment links against a C standard library (like glibc), you can skip raw system calls and directly branch to printf.

Using the C standard printf... .data format: .asciiz "The answer is: %d\n" .text .global main main: # Save return address to stack addi sp, sp, -16 sd ra, 0(sp) la a0, format # 1st argument: Format string li a1, 42 # 2nd argument: Integer replacement value call printf # Invoke standard C printf # Restore return address and exit ld ra, 0(sp) addi sp, sp, 16 li a0, 0 # Return 0 ret

Function Call Register Responsibilities

The hardware registers are divided into two primary categories during a function call: