Skip to main content

伪指令介绍

RISC-V中的伪指令是一些不直接对应于硬件指令的指令,它们在汇编语言中用于简化编程。伪指令的使用使得编写汇编代码变得更加简洁和易于理解,它们在汇编器处理时被翻译成实际的机器指令,从而简化了程序员的工作。伪指令共有 60 条,分为依赖零寄存器x0的 32 条伪指令和与零寄存器x0无关的 28 条伪指令。

1. 依赖零寄存器的伪指令

伪指令基础指令指令集含义
nopaddi x0, x0, 0RV32I/RV64I空操作
neg rd, rssub rd, x0, rsRV32I/RV64I取负
negw rd, rssubw rd, x0, rsRV64I取负字
snez rd, rssltu rd, x0, rsRV32I/RV64I不等于 0 时置位
sltz rd, rsslt rd, rs, x0RV32I/RV64I小于 0 时置位
sgtz rd, rsslt rd, x0, rsRV32I/RV64I大于 0 时置位
beqz rs, offsetbeq rs, x0, offsetRV32I/RV64I等于 0 时分支
bnez rs, offsetbne rs, x0, offsetRV32I/RV64I不等于 0 时分支
blez rs, offsetbge x0, rs, offsetRV32I/RV64I小于等于 0 时分支
bgez rs, offsetbge rs, x0, offsetRV32I/RV64I大于等于 0 时分支
bltz rs, offsetblt rs, x0, offsetRV32I/RV64I小于 0 时分支
bgtz rs, offsetblt x0, rs, offsetRV32I/RV64I大于 0 时分支
j offsetjal x0, offsetRV32I/RV64I跳转
jr rsjalr x0, rs, 0RV32I/RV64I寄存器跳转
retjalr x0, x1, 0RV32I/RV64I子函数返回
tail offsetauipc x6, offset[32:12]
jalr x0, x6, offset[11:0]
RV32I/RV64I尾调用远距离子过程
rdinstret[h] rdcsrrs rd, instret[h], x0读已提交指令计数器
rdcycle[h] rdcsrrs rd, cycle[h], x0读周期计数器
rdtimeh[h] rdcsrrs rd, time[h], x0读实时时钟
csrr rd, csrcsrrs rd, csr, x0RV32I/RV64ICSR 读
csrw csr, rscsrrw x0, csr, rsRV32I/RV64ICSR 写
csrs csr, rscsrrs x0, csr, rsRV32I/RV64ICSR 置位
csrc csr, rscsrrc x0, csr, rsRV32I/RV64ICSR 清位
csrwi csr, immcsrrwi x0, csr, immRV32I/RV64ICSR 写立即数
csrsi csr, immcsrrsi x0, csr, immRV32I/RV64ICSR 置位立即数
csrci csr, immcsrrci x0, csr, immRV32I/RV64ICSR 清位立即数
frcsr rdcsrrs rd, fcsr, x0RV32F/RV64F读浮点 CSR 寄存器
fscsr rscsrrw x0, fcsr, rsRV32F/RV64F写浮点 CSR 寄存器
frrm rdcsrrs rd, frm, x0RV32F/RV64F读浮点写入模式
fsrm rscsrrw x0, frm, rsRV32F/RV64F写浮点写入模式
frflags rdcsrrs rd, fflags, x0RV32F/RV64F读浮点异常标志
fslags rscsrrw x0, fflags, rsRV32F/RV64F写浮点异常标志

2. 与零寄存器无关的伪指令

伪指令基础指令指令集含义
lla rd, symbolauipc rd, symbol[31:12]
add rd, rd, symbol[11:0]
RV32I/RV64I装入局部地址
la rd, symbolSee details for PIC and non-PIC implementationRV32I/RV64I装入地址
li rd, imm多种指令组合RV32I/RV64I装入立即数
mv rd, rsaddi rd, rs, 0RV32I/RV64I复制寄存器
not rd, rsxori rd, rs, -1RV32I/RV64I取反
sext.w rd, rsaddiw rd, rs, 0RV64I符号字扩展
seqz rd, rssltiu rd, rs, 1RV32I/RV64I等于 0 时置位
fmv.s rd, rsfsgnj.s rd, rs, rsRV32F/RV64F复制单精度寄存器
fabs.s rd, rsfsgnjx.s rd, rs, rsRV32F/RV64F单精度浮点绝对值
fneg.s rd, rsfsgnjn.s rd, rs, rsRV32F/RV64F单精度浮点相反数
fmv.d rd, rsfsgnj.d rd, rs, rsRV32D/RV64D复制双精度寄存器
fabs.d rd, rsfsgnjx.d rd, rs, rsRV32D/RV64D双精度浮点绝对值
fneg.d rd, rsfsgnjn.d rd, rs, rsRV32D/RV64D双精度浮点相反数
bgt rs, rt, offsetblt rt, rs, offsetRV32I/RV64I大于时分支
ble rs, rt, offsetbge rt, rs, offsetRV32I/RV64I小于等于时分支
bgtu rs, rt, offsetbltu rt, rs, offsetRV32I/RV64I无符号大于时分支
bleu rs, rt, offsetbgeu rt, rs, offsetRV32I/RV64I无符号小于等于时分支
jal offsetjal x1, offsetRV32I/RV64I跳转并链接
jalr rsjalr x1, rs, 0RV32I/RV64I寄存器跳转并链接
call offsetauipc x1, offset[31:12]
jalr x1, offset[11:0] (x1)
RV32I/RV64I调用远距离过程
fencefence iorw, iorwRV32I/RV64I内存和 I/O 屏障
fscsr rd, rscsrrw rd, fcsr, rsRV32F/RV64F交换浮点 CSR 寄存器
fsrm rd, rscsrrw rd, frm, rsRV32F/RV64F交换浮点舍入模式
fsflags rd, rscsrrw rd, fflags, rsRV32F/RV64F交换浮点异常标志

3. 示例

3.1 进入示例

下载测试代码

下载解压并进入示例目录

3.2 编译

make

3.3 运行

make run

运行后LOG如下

qemu-system-riscv64 -nographic -machine virt -m 128M -bios m_mode.bin -device loader,file=s_mode.bin,addr=0x80200000 -kernel s_mode.elf
_____ ____ _____
/ ____| _ \_ _|
| (___ | |_) || |
\ \___ \| _ < | |
____) | |_) || |_
|_|_____/|____/_____|

li example: rd = 42
mv example: rd = 10
neg example: rd = -5

详见请参考文档:实验环境搭建。