Skip to content
Published at:

附录 C. 伪指令速查表

伪指令(pseudo-instructions)是汇编器提供的语法糖,在汇编时被"展开"为一条或多条真实 RISC-V 指令。理解伪指令的展开规则,有助于阅读反汇编输出和精准控制生成的机器码。以下按功能类别列出 RISC-V 标准伪指令全集。


寄存器间移动

伪指令语法展开为说明
mvmv rd, rsaddi rd, rs, 0rd = rs
notnot rd, rsxori rd, rs, -1rd = ~rs(按位取反)
negneg rd, rssub rd, x0, rsrd = -rs(算术取负)
negwnegw rd, rssubw rd, x0, rsrd = sign_extend(-rs[31:0])(RV64)
sext.wsext.w rd, rsaddiw rd, rs, 0rd = sign_extend(rs[31:0])(RV64)
seqzseqz rd, rssltiu rd, rs, 1rd = (rs == 0) ? 1 : 0
snezsnez rd, rssltu rd, x0, rsrd = (rs != 0) ? 1 : 0
sltzsltz rd, rsslt rd, rs, x0rd = (rs < 0) ? 1 : 0
sgtzsgtz rd, rsslt rd, x0, rsrd = (rs > 0) ? 1 : 0

立即数加载

伪指令语法展开为说明
lili rd, imm由汇编器自动选择最优序列加载 64 位有符号立即数
lili rd, imm(-2048 <= imm < 2048)addi rd, x0, imm小立即数
lili rd, imm(仅低 12 位有效)addi rd, x0, imm
lili rd, imm(仅高 32 位有效)lui rd, imm_hi + addi rd, rd, imm_lo需要 2 条指令
lili rd, imm(任意 64 位值)最多 lui + addi + slli + addi + ...汇编器计算最优分解

地址加载

伪指令语法展开为说明
lala rd, symbolauipc rd, %pcrel_hi(symbol); addi rd, rd, %pcrel_lo(label)加载符号的绝对地址(PC 相对寻址)
llalla rd, symbolauipc rd, %pcrel_hi(symbol); addi rd, rd, %pcrel_lo(label)加载局部符号地址(同 la)
lgalga rd, symbolauipc rd, %got_pcrel_hi(symbol); ld rd, %got_pcrel_lo(label)(rd)通过 GOT 加载全局符号地址(位置无关代码)
larlar rd, symbolauipc rd, %pcrel_hi(symbol); addi rd, rd, %pcrel_lo(label)加载只读符号地址

函数调用与跳转

伪指令语法展开为说明
callcall symbolauipc ra, %pcrel_hi(symbol); jalr ra, %pcrel_lo(label)(ra)函数调用(返回地址存 ra)
tailtail symbolauipc t1, %pcrel_hi(symbol); jalr x0, %pcrel_lo(label)(t1)尾调用优化(不保存返回地址)
retretjalr x0, ra, 0函数返回(跳转至 ra)
jj labeljal x0, label无条件跳转
jrjr rsjalr x0, rs, 0间接跳转(跳转至寄存器地址)
jaljal labeljal x1, label带链接跳转(保存返回地址至 ra)

条件分支扩展

伪指令语法展开为说明
beqzbeqz rs, labelbeq rs, x0, labelrs == 0 则跳转
bnezbnez rs, labelbne rs, x0, labelrs != 0 则跳转
blezblez rs, labelbge x0, rs, labelrs <= 0 则跳转(有符号)
bgezbgez rs, labelbge rs, x0, labelrs >= 0 则跳转(有符号)
bltzbltz rs, labelblt rs, x0, labelrs < 0 则跳转(有符号)
bgtzbgtz rs, labelblt x0, rs, labelrs > 0 则跳转(有符号)
bgtbgt rs1, rs2, labelblt rs2, rs1, labelrs1 > rs2 则跳转(有符号)
bleble rs1, rs2, labelbge rs2, rs1, labelrs1 <= rs2 则跳转(有符号)
bgtubgtu rs1, rs2, labelbltu rs2, rs1, labelrs1 > rs2 则跳转(无符号)
bleubleu rs1, rs2, labelbgeu rs2, rs1, labelrs1 <= rs2 则跳转(无符号)

CSR 操作

伪指令语法展开为说明
csrrcsrr rd, csrcsrrs rd, csr, x0读 CSR(rs1=x0,无写入)
csrwcsrw csr, rscsrrw x0, csr, rs写 CSR(rd=x0,丢弃旧值)
csrscsrs csr, rscsrrs x0, csr, rs置位 CSR(rd=x0,丢弃旧值)
csrccsrc csr, rscsrrc x0, csr, rs清除 CSR(rd=x0,丢弃旧值)
csrwicsrwi csr, uimmcsrrwi x0, csr, uimm立即数写 CSR(uimm[4:0])
csrsicsrsi csr, uimmcsrrsi x0, csr, uimm立即数置位 CSR
csrcicsrci csr, uimmcsrrci x0, csr, uimm立即数清除 CSR

空操作

伪指令语法展开为说明
nopnopaddi x0, x0, 0空操作(不改变任何状态)

浮点伪指令

伪指令语法展开为说明
flwflw fd, symbolauipc xN, %pcrel_hi(symbol); flw fd, %pcrel_lo(label)(xN)从符号地址加载单精度浮点
fldfld fd, symbolauipc xN, %pcrel_hi(symbol); fld fd, %pcrel_lo(label)(xN)从符号地址加载双精度浮点
fswfsw fs, symbol, rtauipc rt, %pcrel_hi(symbol); fsw fs, %pcrel_lo(label)(rt)存储单精度浮点至符号地址
fsdfsd fs, symbol, rtauipc rt, %pcrel_hi(symbol); fsd fs, %pcrel_lo(label)(rt)存储双精度浮点至符号地址
fmv.sfmv.s fd, fsfsgnj.s fd, fs, fs单精度浮点寄存器间移动
fabs.sfabs.s fd, fsfsgnjx.s fd, fs, fs单精度浮点绝对值
fneg.sfneg.s fd, fsfsgnjn.s fd, fs, fs单精度浮点取负
fmv.dfmv.d fd, fsfsgnj.d fd, fs, fs双精度浮点寄存器间移动
fabs.dfabs.d fd, fsfsgnjx.d fd, fs, fs双精度浮点绝对值
fneg.dfneg.d fd, fsfsgnjn.d fd, fs, fs双精度浮点取负

Load/Store 全局符号

伪指令语法展开为说明
lblb rd, symbolauipc rd, %pcrel_hi(symbol); lb rd, %pcrel_lo(label)(rd)从符号地址加载字节
lhlh rd, symbolauipc rd, %pcrel_hi(symbol); lh rd, %pcrel_lo(label)(rd)从符号地址加载半字
lwlw rd, symbolauipc rd, %pcrel_hi(symbol); lw rd, %pcrel_lo(label)(rd)从符号地址加载字
ldld rd, symbolauipc rd, %pcrel_hi(symbol); ld rd, %pcrel_lo(label)(rd)从符号地址加载双字
lbulbu rd, symbolauipc rd, %pcrel_hi(symbol); lbu rd, %pcrel_lo(label)(rd)无符号字节加载
lhulhu rd, symbolauipc rd, %pcrel_hi(symbol); lhu rd, %pcrel_lo(label)(rd)无符号半字加载
lwulwu rd, symbolauipc rd, %pcrel_hi(symbol); lwu rd, %pcrel_lo(label)(rd)无符号字加载
sbsb rs, symbol, rtauipc rt, %pcrel_hi(symbol); sb rs, %pcrel_lo(label)(rt)存储字节至符号地址
shsh rs, symbol, rtauipc rt, %pcrel_hi(symbol); sh rs, %pcrel_lo(label)(rt)存储半字至符号地址
swsw rs, symbol, rtauipc rt, %pcrel_hi(symbol); sw rs, %pcrel_lo(label)(rt)存储字至符号地址
sdsd rs, symbol, rtauipc rt, %pcrel_hi(symbol); sd rs, %pcrel_lo(label)(rt)存储双字至符号地址

数据定义伪指令

伪指令语法说明
.section .text切换至代码段后续指令放入 .text
.section .data切换至数据段后续数据放入 .data
.section .rodata切换至只读数据段
.section .bss切换至未初始化数据段
.globl symbol声明全局符号其他文件可引用
.local symbol声明本地符号仅本文件可见
.align n对齐至 2^n 字节边界填充 nop / 零
.balign n, fill对齐至 n 字节,填充 fill
.zero n预留 n 字节零
.byte expr定义 1 字节
.2byte expr / .half定义 2 字节
.4byte expr / .word定义 4 字节
.8byte expr / .dword定义 8 字节
.float value定义 4 字节 IEEE 754 单精度
.double value定义 8 字节 IEEE 754 双精度
.ascii "string"嵌入 ASCII 字符串(无 \0)
.asciz "string" / .string嵌入 ASCII 字符串(带 \0)
.skip n跳过 n 字节
.size symbol, expr设置符号大小ELF 调试信息
.type symbol, @function标记符号类型ELF 符号表

汇编控制伪指令

伪指令语法说明
.equ name, value定义常量不可重定义
.set name, value定义可重定义常量
.macro name args ... .endm定义宏参数复用
.include "file.s"包含其他汇编文件
.text切换至 .text 段简写
.data切换至 .data 段简写
.rodata切换至 .rodata 段简写
.bss切换至 .bss 段简写
.end汇编结束标记

调用约定快捷伪指令

伪指令语法等价操作说明
push {regs}汇编器展开addi sp, sp, -N; sd reg, offset(sp)入栈(RISC-V 无原生 push,由汇编器生成)
pop {regs}汇编器展开ld reg, offset(sp); addi sp, sp, N出栈

注意:RISC-V 没有原生 push/pop 指令,但 GNU 汇编器和部分工具链提供 push/pop 宏作为便利。


伪指令数量统计

类别数量
寄存器间移动9
立即数/地址加载4
函数调用/跳转6
条件分支扩展10
CSR 操作7
空操作1
浮点运算10
Load/Store 全局符号14
数据定义18
汇编控制9
合计88