RISC-V Assembler Program Structure

Note: Found this code on the web. It is a good place to start.

To Start Writing A Program.

To start writing programs in RISC-V assembly language, you must establish an entry point, divide your code into data and text sections, and use a system call to cleanly exit. Here is a complete, minimal starter template that performs a basic addition and safely terminates.

The RISC-V Starter Template

# Minimal RISC-V Assembly Program .data # Section for declared variables and constants # (Global variables go here) .text # Section for executable machine instructions .global _start # Make the entry label visible to the linker _start: # Execution begins exactly here # 1. Perform a simple operation (5 + 7) li t0, 5 # Load immediate value 5 into register t0 li t1, 7 # Load immediate value 7 into register t1 add t2, t0, t1 # Add t0 and t1, saving the sum (12) in t2 # 2. Setup a clean exit system call (Linux ABI) li a0, 0 # Argument 0: Set exit status code to 0 (Success) li a7, 93 # Argument 7: System call number 93 is 'exit' ecall # Trigger the environment call to the OS

Understanding the Blueprint

Note

  1. In a RISC-V assembler program, _start is the default global entry point recognized by the linker, while start is just a regular, user-defined text label with no intrinsic meaning.

  2. Another View/Choice?

    In RISC-V assembly language, the main label is written as main: followed by the .global main directive to make it visible to the linker.

    Write main: at the start of your primary function code.

    Use .global main so external runtimes or linkers can find the entry point. Place the label inside the .text assembly section.

    .global main .text main: addi sp, sp, -16 # Allocate stack space sd ra, 0(sp) # Save return address # Your instructions go here mv a0, zero # Return 0 status code ld ra, 0(sp) # Restore return address addi sp, sp, 16 # Deallocate stack space ret

Assembler Directives

In RISC-V assembly language, sections are handled using assembler directives. These directives tell the assembler how to organize code and data within the final Executable and Linkable Format (ELF) object binary.

The primary commands used to define and switch between sections are .section, .text, .data, .rodata, and .bss.

For standard ELF sections, you do not need to use the raw .section syntax. The GNU Assembler (GAS) provides direct, built-in shortcuts: