伪指令介绍
RISC-V中的伪指令是一些不直接对应于硬件指令的指令,它们在汇编语言中用于简化编程。伪指令的使用使得编写汇编代码变得更加简洁和易于理解,它们在汇编器处理时被翻译成实际的机器指令,从而简化了程序员的工作。伪指令共有 60 条,分为依赖零寄存器x0的 32 条伪指令和与零寄存器x0无关的 28 条伪指令。
1. 依赖零寄存器的伪指令
| 伪指令 | 基础指令 | 指令集 | 含义 |
|---|---|---|---|
| nop | addi x0, x0, 0 | RV32I/RV64I | 空操作 |
| neg rd, rs | sub rd, x0, rs | RV32I/RV64I | 取负 |
| negw rd, rs | subw rd, x0, rs | RV64I | 取负字 |
| snez rd, rs | sltu rd, x0, rs | RV32I/RV64I | 不等于 0 时置位 |
| sltz rd, rs | slt rd, rs, x0 | RV32I/RV64I | 小于 0 时置位 |
| sgtz rd, rs | slt rd, x0, rs | RV32I/RV64I | 大于 0 时置位 |
| beqz rs, offset | beq rs, x0, offset | RV32I/RV64I | 等于 0 时分支 |
| bnez rs, offset | bne rs, x0, offset | RV32I/RV64I | 不等于 0 时分支 |
| blez rs, offset | bge x0, rs, offset | RV32I/RV64I | 小于等于 0 时分支 |
| bgez rs, offset | bge rs, x0, offset | RV32I/RV64I | 大于等于 0 时分支 |
| bltz rs, offset | blt rs, x0, offset | RV32I/RV64I | 小于 0 时分支 |
| bgtz rs, offset | blt x0, rs, offset | RV32I/RV64I | 大于 0 时分支 |
| j offset | jal x0, offset | RV32I/RV64I | 跳转 |
| jr rs | jalr x0, rs, 0 | RV32I/RV64I | 寄存器跳转 |
| ret | jalr x0, x1, 0 | RV32I/RV64I | 子函数返回 |
| tail offset | auipc x6, offset[32:12] jalr x0, x6, offset[11:0] | RV32I/RV64I | 尾调用远距离子过程 |
| rdinstret[h] rd | csrrs rd, instret[h], x0 | 读已提交指令计数器 | |
| rdcycle[h] rd | csrrs rd, cycle[h], x0 | 读周期计数器 | |
| rdtimeh[h] rd | csrrs rd, time[h], x0 | 读实时时钟 | |
| csrr rd, csr | csrrs rd, csr, x0 | RV32I/RV64I | CSR 读 |
| csrw csr, rs | csrrw x0, csr, rs | RV32I/RV64I | CSR 写 |
| csrs csr, rs | csrrs x0, csr, rs | RV32I/RV64I | CSR 置位 |
| csrc csr, rs | csrrc x0, csr, rs | RV32I/RV64I | CSR 清位 |
| csrwi csr, imm | csrrwi x0, csr, imm | RV32I/RV64I | CSR 写立即数 |
| csrsi csr, imm | csrrsi x0, csr, imm | RV32I/RV64I | CSR 置位立即数 |
| csrci csr, imm | csrrci x0, csr, imm | RV32I/RV64I | CSR 清位立即数 |
| frcsr rd | csrrs rd, fcsr, x0 | RV32F/RV64F | 读浮点 CSR 寄存器 |
| fscsr rs | csrrw x0, fcsr, rs | RV32F/RV64F | 写浮点 CSR 寄存器 |
| frrm rd | csrrs rd, frm, x0 | RV32F/RV64F | 读浮点写入模式 |
| fsrm rs | csrrw x0, frm, rs | RV32F/RV64F | 写浮点写入模式 |
| frflags rd | csrrs rd, fflags, x0 | RV32F/RV64F | 读浮点异常标志 |
| fslags rs | csrrw x0, fflags, rs | RV32F/RV64F | 写浮点异常标志 |
2. 与零寄存器无关的伪指令
| 伪指令 | 基础指令 | 指令集 | 含义 |
|---|---|---|---|
| lla rd, symbol | auipc rd, symbol[31:12] add rd, rd, symbol[11:0] | RV32I/RV64I | 装入局部地址 |
| la rd, symbol | See details for PIC and non-PIC implementation | RV32I/RV64I | 装入地址 |
| li rd, imm | 多种指令组合 | RV32I/RV64I | 装入立即数 |
| mv rd, rs | addi rd, rs, 0 | RV32I/RV64I | 复制寄存器 |
| not rd, rs | xori rd, rs, -1 | RV32I/RV64I | 取反 |
| sext.w rd, rs | addiw rd, rs, 0 | RV64I | 符号字扩展 |
| seqz rd, rs | sltiu rd, rs, 1 | RV32I/RV64I | 等于 0 时置位 |
| fmv.s rd, rs | fsgnj.s rd, rs, rs | RV32F/RV64F | 复制单精度寄存器 |
| fabs.s rd, rs | fsgnjx.s rd, rs, rs | RV32F/RV64F | 单精度浮点绝对值 |
| fneg.s rd, rs | fsgnjn.s rd, rs, rs | RV32F/RV64F | 单精度浮点相反数 |
| fmv.d rd, rs | fsgnj.d rd, rs, rs | RV32D/RV64D | 复制双精度寄存器 |
| fabs.d rd, rs | fsgnjx.d rd, rs, rs | RV32D/RV64D | 双精度浮点绝对值 |
| fneg.d rd, rs | fsgnjn.d rd, rs, rs | RV32D/RV64D | 双精度浮点相反数 |
| bgt rs, rt, offset | blt rt, rs, offset | RV32I/RV64I | 大于时分支 |
| ble rs, rt, offset | bge rt, rs, offset | RV32I/RV64I | 小于等于时分支 |
| bgtu rs, rt, offset | bltu rt, rs, offset | RV32I/RV64I | 无符号大于时分支 |
| bleu rs, rt, offset | bgeu rt, rs, offset | RV32I/RV64I | 无符号小于等于时分支 |
| jal offset | jal x1, offset | RV32I/RV64I | 跳转并链接 |
| jalr rs | jalr x1, rs, 0 | RV32I/RV64I | 寄存器跳转并链接 |
| call offset | auipc x1, offset[31:12] jalr x1, offset[11:0] (x1) | RV32I/RV64I | 调用远距离过程 |
| fence | fence iorw, iorw | RV32I/RV64I | 内存和 I/O 屏障 |
| fscsr rd, rs | csrrw rd, fcsr, rs | RV32F/RV64F | 交换浮点 CSR 寄存器 |
| fsrm rd, rs | csrrw rd, frm, rs | RV32F/RV64F | 交换浮点舍入模式 |
| fsflags rd, rs | csrrw rd, fflags, rs | RV32F/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
详见请参考文档:实验环境搭建。