mcpField
A
assembly-riscv

assembly-riscv

github.com/mohitmishra786开发269495 次安装18 周前更新
代码仓库

关于 assembly-riscv

assembly-riscv 为编写或调试 RISC-V 汇编及相关代码的 Agent 提供指导,涵盖 RV32/RV64 指令、调用约定、ISA 扩展、内联汇编及 QEMU 模拟与 GDB 调试。

主要功能

  1. 01RV32/RV64 指令与寄存器
  2. 02psABI 调用约定
  3. 03ISA 扩展命名
  4. 04GCC/Clang 内联汇编
  5. 05QEMU 模拟与 GDB 调试

适用场景

  1. 01编写 RISC-V 汇编例程
  2. 02按 psABI 传递参数
  3. 03为目标选择 ISA 扩展
  4. 04模拟或调试 RISC-V 程序

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill assembly-riscv

安装后在 Claude Code 中输入/assembly-riscv确认已加载。

附带文件references/riscv-abi.md

详细介绍

RISC-V 汇编

用途

指导 Agent 进行 RISC-V 汇编编程:RV32/RV64 指令集、寄存器命名和调用约定(psABI)、ISA 扩展命名、使用 GCC/Clang 编写内联汇编、压缩(RVC)指令,以及基于 QEMU 的模拟和 GDB 远程调试。

触发条件

  • “如何编写 RISC-V 汇编?”
  • “RISC-V 调用约定使用哪些寄存器?”
  • “如何在 C 中使用 RISC-V 内联汇编?”
  • “RISC-V 扩展字母(IMAFD)是什么意思?”
  • “如何使用 QEMU 模拟 RISC-V?”
  • “如何使用 GDB 调试 RISC-V 代码?”

工作流

1. 寄存器文件和调用约定

RISC-V 有 32 个整数寄存器(x0–x31),及其 ABI 名称:

寄存器ABI 名称作用保存方
x0zero硬连线为零—
x1ra返回地址调用方
x2sp栈指针被调用方
x3gp全局指针—
x4tp线程指针—
x5–x7t0–t2临时寄存器调用方
x8s0/fp帧指针被调用方
x9s1保存寄存器被调用方
x10–x11a0–a1参数 / 返回值调用方
x12–x17a2–a7参数调用方
x18–x27s2–s11保存寄存器被调用方
x28–x31t3–t6临时寄存器调用方

浮点寄存器(F 扩展):f0–f31(fa0–fa7 用于传递参数)。

2. 基本指令
# Arithmetic (R and I type)
add   a0, a1, a2      # a0 = a1 + a2
sub   a0, a1, a2      # a0 = a1 - a2
addi  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)

# Logical
and   a0, a1, a2      # bitwise AND
or    a0, a1, a2      # bitwise OR
xor   a0, a1, a2      # bitwise XOR
sll   a0, a1, a2      # shift left logical
srl   a0, a1, a2      # shift right logical (unsigned)
sra   a0, a1, a2      # shift right arithmetic (signed)

# Load / store
lw    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 word
sd    a0, 0(sp)       # store doubleword (RV64)

# Branches (compare and branch)
beq   a0, a1, label   # branch if equal
bne   a0, a1, label   # branch if not equal
blt   a0, a1, label   # branch if less than (signed)
bltu  a0, a1, label   # branch if less than (unsigned)
bge   a0, a1, label   # branch if ≥ (signed)

# Jumps
j     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. 最简函数(psABI 调用约定)
.section .text
.global add_numbers
# int add_numbers(int a, int b);  — a in a0, b in a1, return in a0
add_numbers:
    add   a0, a0, a1   # result = a + b
    ret                # return (jalr zero, ra, 0)

.global factorial
# long factorial(int n);  — n in a0
factorial:
    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 扩展命名

RISC-V 扩展会以字符串形式组合在基础 ISA 之后:

字母扩展描述
I整数基础 32/64 位整数(RV32I、RV64I)
M乘法整数乘法和除法
A原子原子内存操作(lr/sc、AMO)
F浮点单精度浮点数
D双精度双精度浮点数
C压缩16 位压缩指令
G通用= IMAFD(简写)
V向量向量指令(SIMD)
ZicsrCSR控制 / 状态寄存器访问
ZifenceiFence.i指令获取栅栏
Zba/Zbb/Zbc/Zbs位操作位操作(B 扩展组)
ZtsoTSO全存储顺序内存模型

常见目标:

  • 嵌入式:rv32imac — 无浮点,支持原子操作和压缩指令
  • Linux 应用:rv64gc — 完整通用扩展 + 压缩指令
  • 高性能:rv64gcv — + 向量扩展
5. 内联汇编(GCC/Clang)
// 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 swap
static 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 fence
static 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. 压缩指令(RVC)

满足以下条件时,RVC 会用 16 位版本替换常见的 32 位指令:

  • 寄存器位于 x8–x15(适用于 c. 版本)
  • 立即数适合更小的字段
  • 符合特定的指令模式
# Enable C extension in GCC
riscv64-linux-gnu-gcc -march=rv64gc prog.c -o prog

# Check if compressed instructions were generated
riscv64-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 模拟和 GDB
# Install QEMU RISC-V
apt-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 session
riscv64-linux-gnu-gdb prog
(gdb) target remote :1234
(gdb) load
(gdb) break main
(gdb) continue

有关 RISC-V psABI 调用约定的详细信息,请参阅 references/riscv-abi.md。

相关技能

  • 使用 skills/low-level-programming/assembly-arm 对比 AArch64
  • 使用 skills/low-level-programming/assembly-x86 了解 x86-64 汇编
  • 使用 skills/embedded/openocd-jtag 调试真实的 RISC-V 硬件
  • 使用 skills/compilers/cross-gcc 配置 RISC-V 交叉编译

评论

支持 Markdown