Assembly Riscv

mohitmishra786/low-level-dev-skills/skills/low-level-programming/assembly-riscv

by mohitmishra786bdc58472fa9fNo license253 starsListed Oct 9, 2026Updated Oct 9, 2026Repository updated 3 months ago

RISC-V assembly skill for RV32/RV64 programming. Use when working with the RISC-V ISA, calling conventions (psABI), inline assembly with GCC/Clang, understanding extension naming (IMAFD), compressed instructions, or simulating RISC-V with QEMU and GDB remote debugging. Activates on queries about RISC-V assembly, RV32, RV64, RISC-V calling convention, RISC-V inline asm, RISC-V extensions, QEMU RISC-V, or RISC-V GDB.

Instructions onlySoftware Development
AI-generated overview

Guides RISC-V assembly programming for RV32/RV64, covering registers, calling conventions, inline asm, extensions, and QEMU/GDB simulation.

What it does
This skill provides reference guidance for writing RISC-V assembly: the integer and floating-point register files with ABI names, common arithmetic, logical, load/store, branch and jump instructions, and a minimal function following the psABI calling convention. It also explains ISA extension naming (IMAFD, G, V, Zicsr and others), inline assembly with GCC/Clang, compressed (RVC) instructions, and QEMU user- and system-mode simulation with GDB remote debugging. A bundled reference file covers psABI calling convention details.
When to use it
Use it when writing or reviewing RISC-V assembly, when you need the RISC-V calling convention register roles, or when working with inline asm, extension naming, compressed instructions, or QEMU/GDB RISC-V simulation.
Requirements
No scripts; instructions and a reference document only. Examples assume a RISC-V cross toolchain (GCC/Clang, objdump, GDB) and QEMU RISC-V packages, which must be installed separately.

RISC-V Assembly

Purpose

Guide agents through RISC-V assembly programming: RV32/RV64 instruction sets, register naming and calling conventions (psABI), ISA extension naming, inline assembly with GCC/Clang, compressed (RVC) instructions, and QEMU-based simulation with GDB remote debugging.

Triggers

  • "How do I write RISC-V assembly?"
  • "What are the RISC-V calling convention registers?"
  • "How do I use inline asm for RISC-V in C?"
  • "What do RISC-V extension letters mean (IMAFD)?"
  • "How do I simulate RISC-V with QEMU?"
  • "How do I debug RISC-V code with GDB?"

Workflow

1. Register file and calling convention

RISC-V has 32 integer registers (x0–x31) with ABI names:

RegisterABI nameRoleSaved by
x0zeroHard-wired zero—
x1raReturn addressCaller
x2spStack pointerCallee
x3gpGlobal pointer—
x4tpThread pointer—
x5–x7t0–t2TemporariesCaller
x8s0/fpFrame pointerCallee
x9s1Saved registerCallee
x10–x11a0–a1Arguments / return valuesCaller
x12–x17a2–a7ArgumentsCaller
x18–x27s2–s11Saved registersCallee
x28–x31t3–t6TemporariesCaller

Floating-point registers (F extension): f0–f31 (fa0–fa7 for arguments).

2. Basic instructions

asm
# Arithmetic (R and I type)add   a0, a1, a2      # a0 = a1 + a2sub   a0, a1, a2      # a0 = a1 - a2addi  a0, a1, 42      # a0 = a1 + 42 (immediate)mul   a0, a1, a2      # a0 = a1 * a2 (M extension)div   a0, a1, a2      # signed divide (M extension)rem   a0, a1, a2      # remainder (M extension)
# Logicaland   a0, a1, a2      # bitwise ANDor    a0, a1, a2      # bitwise ORxor   a0, a1, a2      # bitwise XORsll   a0, a1, a2      # shift left logicalsrl   a0, a1, a2      # shift right logical (unsigned)sra   a0, a1, a2      # shift right arithmetic (signed)
# Load / storelw    a0, 0(sp)       # load word (32-bit)ld    a0, 0(sp)       # load doubleword (64-bit, RV64)lh    a0, 4(sp)       # load halfword (sign-extended)lbu   a0, 8(sp)       # load byte (zero-extended)sw    a0, 0(sp)       # store wordsd    a0, 0(sp)       # store doubleword (RV64)
# Branches (compare and branch)beq   a0, a1, label   # branch if equalbne   a0, a1, label   # branch if not equalblt   a0, a1, label   # branch if less than (signed)bltu  a0, a1, label   # branch if less than (unsigned)bge   a0, a1, label   # branch if ≥ (signed)
# Jumpsj     label           # unconditional jump (pseudoinstruction: jal x0, label)jal   ra, func        # jump and link (call)jalr  zero, ra, 0     # jump to ra (return: pseudoinstruction: ret)

3. Minimal function (psABI calling convention)

asm
.section .text.global add_numbers# int add_numbers(int a, int b);  — a in a0, b in a1, return in a0add_numbers:    add   a0, a0, a1   # result = a + b    ret                # return (jalr zero, ra, 0)
.global factorial# long factorial(int n);  — n in a0factorial:    addi  sp, sp, -16      # allocate stack frame    sd    ra, 8(sp)        # save return address (RV64)    sd    s0, 0(sp)        # save s0 (callee-saved)
    mv    s0, a0           # s0 = n    li    a0, 1            # default return 1    blez  s0, .done        # if n <= 0, return 1
    addi  a0, s0, -1      # a0 = n - 1    call  factorial        # recursive call: factorial(n-1)    mul   a0, a0, s0       # a0 = result * n
.done:    ld    ra, 8(sp)        # restore ra    ld    s0, 0(sp)        # restore s0    addi  sp, sp, 16       # deallocate    ret

4. ISA extension naming

RISC-V extensions are combined as a string after the base ISA:

LetterExtensionDescription
IIntegerBase 32/64-bit integer (RV32I, RV64I)
MMultiplyInteger multiply and divide
AAtomicAtomic memory operations (lr/sc, AMOs)
FFloatSingle-precision float
DDoubleDouble-precision float
CCompressed16-bit compressed instructions
GGeneral= IMAFD (shorthand)
VVectorVector instructions (SIMD)
ZicsrCSRControl/status register access
ZifenceiFence.iInstruction-fetch fence
Zba/Zbb/Zbc/ZbsBit manipulationBit ops (B extension set)
ZtsoTSOTotal Store Ordering memory model

Common targets:

  • Embedded: rv32imac — no floating point, with atomics and compressed
  • Linux app: rv64gc — full general + compressed
  • High performance: rv64gcv — + vector

5. Inline assembly (GCC/Clang)

c
// Read a CSR register (e.g., cycle counter)static inline uint64_t read_cycle(void) {    uint64_t val;    asm volatile ("rdcycle %0" : "=r"(val));    return val;}
// Atomic swapstatic inline int atomic_swap(int *ptr, int new_val) {    int old;    asm volatile (        "amoswap.w.aqrl %0, %2, (%1)"        : "=r"(old)        : "r"(ptr), "r"(new_val)        : "memory"    );    return old;}
// Memory fencestatic inline void memory_fence(void) {    asm volatile ("fence rw, rw" ::: "memory");}
// CSR read/write#define csr_read(csr) ({                    \    uint64_t _v;                            \    asm volatile ("csrr %0, " #csr : "=r"(_v)); \    _v;                                     \})
uint64_t mstatus = csr_read(mstatus);

6. Compressed instructions (RVC)

RVC replaces common 32-bit instructions with 16-bit versions when:

  • Register is in x8–x15 (for c. versions)
  • Immediate fits in smaller field
  • Specific instruction patterns match
bash
# Enable C extension in GCCriscv64-linux-gnu-gcc -march=rv64gc prog.c -o prog
# Check if compressed instructions were generatedriscv64-linux-gnu-objdump -d prog | grep "c\."# c.addi, c.ld, c.sw, c.j, etc.
# Disable compressed (for debugging or targets without C)riscv64-linux-gnu-gcc -march=rv64g prog.c -o prog

7. QEMU simulation and GDB

bash
# Install QEMU RISC-Vapt-get install qemu-user qemu-system-riscv64
# User-mode emulation (run RV64 binary on x86 host)qemu-riscv64 ./prog
# System emulation (full bare-metal VM)qemu-system-riscv64 \  -machine virt \  -nographic \  -kernel firmware.elf \  -gdb tcp::1234 \  -S     # start paused
# GDB remote sessionriscv64-linux-gnu-gdb prog(gdb) target remote :1234(gdb) load(gdb) break main(gdb) continue

For the RISC-V psABI calling convention details, see references/riscv-abi.md [blocked].

Related skills

  • Use skills/low-level-programming/assembly-arm for AArch64 comparison
  • Use skills/low-level-programming/assembly-x86 for x86-64 assembly
  • Use skills/embedded/openocd-jtag for real hardware RISC-V debugging
  • Use skills/compilers/cross-gcc for RISC-V cross-compilation setup

Source and attribution

Source:mohitmishra786/low-level-dev-skillsinskills/low-level-programming/assembly-riscvat commitbdc5847

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal