一起学RISC-V汇编第6讲之伪指令
伪指令是方便程序员使用,相当于为实际指令取的别名,编程时可以直接使用伪指令。
上一章已经列出了RISC-V中的伪指令,只是比较分散,这一章以另一个视角重新整理一下伪指令,表格来源于《RISC-V 开放架构设计之道 1.0.0》
1 RISC-V伪指令列表
伪指令一共60条,分为依赖零寄存器x0的32条伪指令以及与零寄存器x0 无关的28条伪指令。
1.1 依赖零寄存器x0的32条伪指令
伪指令
基础指令
指令集
含义
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, offet
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
写浮点异常标志
1.2 与零寄存器x0 无关的28条伪指令
伪指令
基础指令
指令集
含义
lla rd, symbol
auipc rd, symbol[31:12]add rd, rd, symbol[11:0]
RV32I/RV64I
装入局部地址
la rd, symbol
PIC: auipc rd, GOT[symbol][31:12]l {w|d} rd, GOT[symbol][11:0](rd) 非PIC: 与 lla rd, symbol 相同
RV32I/RV64I
装入地址
l{b|h|w|d} rd, symbol
auipc rd, symbol[31:12]l{b|h|w|d} rd, symbol[11:0](rd)
读全局符号
s{b|h|w|d} rd, symbol, rt
auipc rt, symbol[31:12]s{b|h|w|d} rd, symbol[11:0](rt)
写全局符号
fl{w|d} rd, symbol, rt
auipc rt, symbol[31:12]fl{w|d} rd,symbol[11:0](rt)
读全局浮点符号
fs{w|d} rd, symbol, rt
auipc rt, symbol[31:12]fs{w|d} rd,symbol[11:0](rt)
写全局浮点符号
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
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, fcrs, rs
RV32F/RV64F
交换浮点csr寄存器
fsrm rd, rs
csrrw rd, frm, rs
RV32F/RV64F
交换浮点舍入模式
fsflags rd, rs
csrrw rd, fflags, rs
RV32F/RV64F
交换浮点异常标志
参考:
riscv gcc中添加custom自定义指令
https://sourceware.org/binutils/docs/as/RISC_002dV_002dFormats.html