关于 assembly-riscv
assembly-riscv 为编写或调试 RISC-V 汇编及相关代码的 Agent 提供指导,涵盖 RV32/RV64 指令、调用约定、ISA 扩展、内联汇编及 QEMU 模拟与 GDB 调试。
主要功能
- 01RV32/RV64 指令与寄存器
- 02psABI 调用约定
- 03ISA 扩展命名
- 04GCC/Clang 内联汇编
- 05QEMU 模拟与 GDB 调试
适用场景
- 01编写 RISC-V 汇编例程
- 02按 psABI 传递参数
- 03为目标选择 ISA 扩展
- 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 名称 | 作用 | 保存方 |
|---|---|---|---|
| x0 | zero | 硬连线为零 | — |
| x1 | ra | 返回地址 | 调用方 |
| x2 | sp | 栈指针 | 被调用方 |
| x3 | gp | 全局指针 | — |
| x4 | tp | 线程指针 | — |
| x5–x7 | t0–t2 | 临时寄存器 | 调用方 |
| x8 | s0/fp | 帧指针 | 被调用方 |
| x9 | s1 | 保存寄存器 | 被调用方 |
| x10–x11 | a0–a1 | 参数 / 返回值 | 调用方 |
| x12–x17 | a2–a7 | 参数 | 调用方 |
| x18–x27 | s2–s11 | 保存寄存器 | 被调用方 |
| x28–x31 | t3–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) |
| Zicsr | CSR | 控制 / 状态寄存器访问 |
| Zifencei | Fence.i | 指令获取栅栏 |
| Zba/Zbb/Zbc/Zbs | 位操作 | 位操作(B 扩展组) |
| Ztso | TSO | 全存储顺序内存模型 |
常见目标:
- 嵌入式:
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