RISC-V汇编学习(三)—— RV指令集
有了前两节对于RISC-V汇编、寄存器、汇编语法等的认识,本节开始介绍RISC-V指令集和伪指令。
前面说了RISC-V的模块化特点,是以RV32I为作为ISA的核心模块,其他都是要基于此为基础,可以这样认为:RISC-V ISA = 基本整数指令集+多个可选扩展指令集;另外RISC-V的ISA spec上是从指令类型和指令格式开始介绍指令的;但从一个嵌入式软件开发人员的角度来说,不是特别适合学习和记忆,所以我这里简单罗列下,不多讲解,感兴趣可以参考spec。
1 指令类型
1.1 组成格式

所有RISC-V指令都是固定长度的32位,这有助于简化指令解码过程。每个指令都由以下几个关键部分组成:
- opcode:这是7位的操作码,用来标识指令的基本类型。
- funct3:这是一个3位的功能码,与opcode一起使用以进一步细化指令的类别。
- funct7:某些指令使用额外的7位功能码来更精确地定义指令的行为。
- rs1/rs2/rd:这些是5位的寄存器地址,分别代表源寄存器1、源寄存器2和目的寄存器。
- imm:立即数字段,其大小和位置根据指令类型的不同而变化。
1.2 类型
RISC-V定义了几种基本的指令格式,每一种都针对特定类型的运算或操作。这些格式包括:R型、I型、S型、B型、U型、J型。
-
R型(Register)
用于寄存器间的算术/逻辑运算(如ADD x1, x2, x3)
字段:opcode确定操作类型,funct3和funct7进一步指定具体操作(如区分ADD与SUB) -
I型(Immediate)
用于立即数操作(如ADDI x1, x2, 42)或加载指令(如LW x1, 100(x2))
立即数:12位符号扩展,直接嵌入指令中 -
S型(Store)
存储数据到内存(如SW x3, 200(x4))
立即数:12位拆分为imm[11:5]和imm[4:0],组合后作为偏移地址。 -
B型(Branch)
条件分支(如BEQ x1, x2, label)
立即数:13位(符号扩展后左移1位),拆分为imm[12|10:5|4:1|11],支持更大跳转范围 -
U型(Upper Immediate)
加载高20位立即数(如LUI x1, 0x12345)或构造地址(如AUIPC)
立即数:20位直接嵌入高位,低12位由后续指令补充 -
J型(Jump)
长距离无条件跳转(如JAL x1, label)
立即数:20位符号扩展后左移1位,支持±1MB跳转范围
但在实际应用中,我们也很难记住这么汇编指令机器码,一般情况下也不会有错,具体可以参考spec。
2 指令命名
下图是RV32I基础指令集的⼀⻚图形表示,将有下划线的字⺟从左到右连接起来,即可组成完整的RV32I指令集。集合标志{}内列举了指令的所有变体,变体⽤加下划线的字⺟或下划线字符_表示,特别的,下划线字符_表示对于此指令变体不需⽤字符表示

以slt指令为例,如下示意图:大括号{ }内列举了每组指令的所有变体,这些变体通过带下滑线的字母(单独的下划线_表示空字段),从左到右连接带下滑线的字母即可组成完整的指令集,比如slt意思是set less than,相当于是一种缩写,完整语句方便我们快速清晰的理解指令的作用。

上图可以表示:slt、slti、sltu、sltiu 这4条RVI指令。
下面将列举以下RISC-V指令集:
- RVI(包括RV32I与RV64I)
- RVM(包括RV32M与RV64M)
- RVFD(包括RV32FD与RV64FD)
- RVA(包括RV32A与RV64A)
3 RVI指令集
RVI是 RISC-V 指令集架构的基础部分,它定义了32位整数运算的核心指令集。RVI 包括 RV32I(32位整数指令集)和 RV64I(64位整数指令集),它们为处理器提供了执行基本计算任务的能力;包括:内存操作指令、逻辑指令、分支和跳转指令、算术指令等等,下面就一一列举。
3.1 内存操作指令
在RISC-V中,内存操作主要通过加载(Load)和存储(Store)两类指令来实现。这些指令允许程序从内存读取数据到寄存器(Load),或将寄存器中的数据写入内存(Store)

| 指令 | 格式 | 功能描述 | 操作(伪代码) | 指令集 |
|---|---|---|---|---|
| LB | lb rd, offset(rs1) | 加载字节(符号扩展) | rd = SignExt(Mem[rs1 + offset][7:0]) | RV32I / RV64I |
| LBU | lbu rd, offset(rs1) | 加载字节(无符号扩展) | rd = ZeroExt(Mem[rs1 + offset][7:0]) | RV32I / RV64I |
| LH | lh rd, offset(rs1) | 加载半字(符号扩展) | rd = SignExt(Mem[rs1 + offset][15:0]) | RV32I / RV64I |
| LHU | lhu rd, offset(rs1) | 加载半字(无符号扩展) | rd = ZeroExt(Mem[rs1 + offset][15:0]) | RV32I / RV64I |
| LW | lw rd, offset(rs1) | 加载字(RV32I:32位;RV64I:符号扩展至64位) | RV32I: rd = Mem[rs1 + offset][31:0]RV64I: rd = SignExt(Mem[rs1 + offset][31:0]) | RV32I / RV64I |
| LWU | lwu rd, offset(rs1) | 加载字(无符号扩展至64位) | rd = ZeroExt(Mem[rs1 + offset][31:0]) | RV64I |
| LD | ld rd, offset(rs1) | 加载双字(64位) | rd = Mem[rs1 + offset][63:0] | RV64I |
| SB | sb rs2, offset(rs1) | 存储字节 | Mem[rs1 + offset] = rs2[7:0] | RV32I / RV64I |
| SH | sh rs2, offset(rs1) | 存储半字 | Mem[rs1 + offset] = rs2[15:0] | RV32I / RV64I |
| SW | sw rs2, offset(rs1) | 存储字 | Mem[rs1 + offset] = rs2[31:0] | RV32I / RV64I |
| SD | sd rs2, offset(rs1) | 存储双字 | Mem[rs1 + offset] = rs2[63:0] | RV64I |
3.2 算术指令
算术指令狭义定义:仅包含加法、减法及其直接相关的操作,用于寄存器或寄存器与立即数之间的数值运算。

| 指令 | 格式 | 功能描述 | 操作(伪代码) | 指令集 |
|---|---|---|---|---|
| 基础加减指令 | ||||
| ADD | add rd, rs1, rs2 | 加法(忽略溢出) | rd = rs1 + rs2 | RV32I / RV64I |
| SUB | sub rd, rs1, rs2 | 减法(忽略溢出) | rd = rs1 - rs2 | RV32I / RV64I |
| ADDI | addi rd, rs1, imm | 立即数加法(符号扩展立即数) | rd = rs1 + SignExt(imm) | RV32I / RV64I |
| RV64I 扩展加减指令 | ||||
| ADDIW | addiw rd, rs1, imm | 立即数加法(32位,符号扩展至64位) | rd = SignExt((rs1 + SignExt(imm))[31:0]) | RV64I |
| ADDW | addw rd, rs1, rs2 | 加法(32位,符号扩展至64位) | rd = SignExt((rs1 + rs2)[31:0]) | RV64I |
| SUBW | subw rd, rs1, rs2 | 减法(32位,符号扩展至64位) | rd = SignExt((rs1 - rs2)[31:0]) | RV64I |
| 高位立即数构建指令 | ||||
| LUI | lui rd, imm | 加载高位立即数(imm[31:12]) | rd = imm << 12 | RV32I / RV64I |
| AUIPC | auipc rd, imm | 将高位立即数与 PC 相加 | rd = PC + (imm << 12) | RV32I / RV64I |
伪指令表格:
| 伪指令 | 格式 | 功能描述 | 实际转换(基础指令) | 适用指令集 |
|---|---|---|---|---|
| 寄存器操作 | ||||
| MV | mv rd, rs | 寄存器间移动值 | addi rd, rs, 0 | RV32I / RV64I |
| NEG | neg rd, rs | 取负值(rd = -rs) | sub rd, x0, rs | RV32I / RV64I |
| NEGW | negw rd, rs | 取负值(32位操作,符号扩展) | subw rd, x0, rs | RV64I |
| 立即数操作 | ||||
| LI | li rd, imm | 加载任意立即数到寄存器 | 若 imm 在 12 位有符号范围内:addi rd, x0, imm否则: lui rd, imm[31:12] + addi rd, rd, imm[11:0] | RV32I / RV64I |
| 地址加载 | ||||
| LA | la rd, symbol | 加载绝对地址(链接时解析) | auipc rd, offset_hi + addi rd, rd, offset_lo或 lui rd, offset_hi + addi rd, rd, offset_lo | RV32I / RV64I |
| LLA | lla rd, symbol | 加载本地地址(PC相对,位置无关) | auipc rd, offset_hi + addi rd, rd, offset_lo | RV32I / RV64I |
| 符号扩展 | ||||
| SEXT.W | sext.w rd, rs | 将低32位符号扩展至64位(RV64I) | addiw rd, rs, 0 | RV64I |
| 空操作 | ||||
| NOP | nop | 空操作(无实际效果) | addi x0, x0, 0 | RV32I / RV64I |
3.3 移位指令
移位指令用于对寄存器中的数据进行位级左移或右移,分为以下两类:
-
- 寄存器移位:移位位数由另一个寄存器的低 5 位(RV32I)或低 6 位(RV64I)指定。
-
- 立即数移位:移位位数由指令中的立即数字段直接指定。

- 立即数移位:移位位数由指令中的立即数字段直接指定。
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 指令集 |
|---|---|---|---|---|
| 逻辑左移 | ||||
| SLL | sll rd, rs1, rs2 | 逻辑左移(低位补零) | rd = rs1 << (rs2[4:0])(RV32I,取低5位)rd = rs1 << (rs2[5:0])(RV64I,取低6位) | RV32I / RV64I |
| SLLI | slli rd, rs1, shamt | 立即数逻辑左移 | rd = rs1 << shamt(shamt范围:RV32I为 0–31,RV64I为 0–63) | RV32I / RV64I |
| SLLW | sllw rd, rs1, rs2 | 32位逻辑左移(RV64I,低32位操作) | rd = SignExt((rs1[31:0] << rs2[4:0])) | RV64I |
| SLLIW | slliw rd, rs1, shamt | 32位立即数逻辑左移(RV64I) | rd = SignExt((rs1[31:0] << shamt)[31:0])(shamt范围:0–31) | RV64I |
| 逻辑右移 | ||||
| SRL | srl rd, rs1, rs2 | 逻辑右移(高位补零) | rd = rs1 >> (rs2[4:0])(RV32I)rd = rs1 >> (rs2[5:0])(RV64I) | RV32I / RV64I |
| SRLI | srli rd, rs1, shamt | 立即数逻辑右移 | rd = rs1 >> shamt | RV32I / RV64I |
| SRLW | srlw rd, rs1, rs2 | 32位逻辑右移(RV64I,低32位操作) | rd = SignExt((rs1[31:0] >> rs2[4:0])) | RV64I |
| SRLIW | srliw rd, rs1, shamt | 32位立即数逻辑右移(RV64I) | rd = SignExt((rs1[31:0] >> shamt)[31:0])(shamt范围:0–31) | RV64I |
| 算术右移 | ||||
| SRA | sra rd, rs1, rs2 | 算术右移(高位补符号位) | rd = rs1 >>> (rs2[4:0])(RV32I)rd = rs1 >>> (rs2[5:0])(RV64I) | RV32I / RV64I |
| SRAI | srai rd, rs1, shamt | 立即数算术右移 | rd = rs1 >>> shamt | RV32I / RV64I |
| SRAW | sraw rd, rs1, rs2 | 32位算术右移(RV64I,低32位操作) | rd = SignExt((rs1[31:0] >>> rs2[4:0])) | RV64I |
| SRAIW | sraiw rd, rs1, shamt | 32位立即数算术右移(RV64I) | rd = SignExt((rs1[31:0] >>> shamt)[31:0])(shamt范围:0–31) | RV64I |
3.4 逻辑指令
逻辑指令用于对寄存器中的数据进行按位操作,分为以下两类:
- 1.寄存器-寄存器操作:两个寄存器之间的按位运算。
- 2.寄存器-立即数操作:寄存器与符号扩展后的立即数进行按位运算。

| 指令 | 格式 | 功能描述 | 操作(伪代码) | 指令集 |
|---|---|---|---|---|
| 按位与操作 | ||||
| AND | and rd, rs1, rs2 | 按位与 | rd = rs1 & rs2 | RV32I / RV64Ity-reference |
| ANDI | andi rd, rs1, imm | 立即数按位与(符号扩展立即数) | rd = rs1 & SignExt(imm) | RV32I / RV64Ity-reference |
| 按位或操作 | ||||
| OR | or rd, rs1, rs2 | 按位或 | `rd = rs1 | rs2` |
| ORI | ori rd, rs1, imm | 立即数按位或(符号扩展立即数) | `rd = rs1 | SignExt(imm)` |
| 按位异或操作 | ||||
| XOR | xor rd, rs1, rs2 | 按位异或 | rd = rs1 ^ rs2 | RV32I / RV64Ity-reference |
| XORI | xori rd, rs1, imm | 立即数按位异或(符号扩展立即数) | rd = rs1 ^ SignExt(imm) | RV32I / RV64Ity-reference |
伪指令:
| 伪指令 | 格式 | 功能描述 | 实际转换(基础指令) | 适用指令集 |
|---|---|---|---|---|
| NOT | not rd, rs | 按位取反(rd = ~rs) | xori rd, rs, -1 | RV32I / RV64I |
3.5 比较-置位指令
指令根据两个操作数的比较结果设置目标寄存器的值为 1 或 0,用于条件判断和逻辑控制,支持有符号和无符号比较。

| 指令 | 格式 | 功能描述 | 操作(伪代码) | 指令集 |
|---|---|---|---|---|
| 有符号比较 | ||||
| SLT | slt rd, rs1, rs2 | 有符号比较:若 rs1 < rs2,则 rd = 1,否则 rd = 0 | rd = (rs1 < rs2) ? 1 : 0 (有符号比较) | RV32I / RV64Ity-reference |
| SLTI | slti rd, rs1, imm | 有符号立即数比较:若 rs1 < SignExt(imm),则 rd = 1 | rd = (rs1 < SignExt(imm)) ? 1 : 0 | RV32I / RV64Ity-reference |
| 无符号比较 | ||||
| SLTU | sltu rd, rs1, rs2 | 无符号比较:若 rs1 < rs2,则 rd = 1 | rd = (rs1 < rs2) ? 1 : 0 (无符号比较) | RV32I / RV64Ity-reference |
| SLTIU | sltiu rd, rs1, imm | 无符号立即数比较(立即数符号扩展后按无符号比较):若 rs1 < SignExt(imm),则 rd = 1 | rd = (rs1 < SignExt(imm)) ? 1 : 0 (无符号比较) | RV32I / RV64Ity-reference |
伪指令:
| 伪指令 | 格式 | 功能描述 | 实际转换(基础指令) | 适用指令集 |
|---|---|---|---|---|
| 零值判断 | ||||
| SEQZ | seqz rd, rs | 若 rs == 0,则 rd = 1,否则 0 | sltiu rd, rs, 1 | RV32I / RV64I |
| SNEZ | snez rd, rs | 若 rs ≠ 0,则 rd = 1,否则 0 | sltu rd, x0, rs | RV32I / RV64I |
| 符号判断 | ||||
| SLTZ | sltz rd, rs | 若 rs < 0(有符号),则 rd = 1 | slt rd, rs, x0 | RV32I / RV64I |
| SGTZ | sgtz rd, rs | 若 rs > 0(有符号),则 rd = 1 | slt rd, x0, rs | RV32I / RV64I |
| 非零符号判断 | ||||
| SLEZ | slez rd, rs | 若 rs ≤ 0(有符号),则 rd = 1 | slt rd, x0, rs → xori rd, rd, 1 | RV32I / RV64I |
| SGEZ | sgez rd, rs | 若 rs ≥ 0(有符号),则 rd = 1 | slt rd, rs, x0 → xori rd, rd, 1 | RV32I / RV64I |
3.6 分支指令
分支指令用于控制程序流程,根据条件或地址跳转执行目标代码,均为 B-Type 或 J-Type 格式。

条件分支指令
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 指令集 |
|---|---|---|---|---|
| BEQ | beq rs1, rs2, offset | 若 rs1 == rs2,跳转到 PC + offset | if (rs1 == rs2) PC += SignExt(offset << 1) | RV32I / RV64I |
| BNE | bne rs1, rs2, offset | 若 rs1 ≠ rs2,跳转到 PC + offset | if (rs1 != rs2) PC += SignExt(offset << 1) | RV32I / RV64I |
| BLT | blt rs1, rs2, offset | 若 rs1 < rs2(有符号),跳转 | if (rs1 < rs2) PC += SignExt(offset << 1) | RV32I / RV64I |
| BGE | bge rs1, rs2, offset | 若 rs1 ≥ rs2(有符号),跳转 | if (rs1 >= rs2) PC += SignExt(offset << 1) | RV32I / RV64I |
| BLTU | bltu rs1, rs2, offset | 若 rs1 < rs2(无符号),跳转 | if (rs1 < rs2) PC += SignExt(offset << 1) | RV32I / RV64I |
| BGEU | bgeu rs1, rs2, offset | 若 rs1 ≥ rs2(无符号),跳转 | if (rs1 >= rs2) PC += SignExt(offset << 1) | RV32I / RV64I |
条件分支伪指令
| 伪指令 | 格式 | 功能描述 | 实际转换(基础指令) | 适用指令集 |
|---|---|---|---|---|
| BEQZ | beqz rs, offset | 若 rs == 0,跳转到 offset | beq rs, x0, offset | RV32I / RV64I |
| BNEZ | bnez rs, offset | 若 rs ≠ 0,跳转到 offset | bne rs, x0, offset | RV32I / RV64I |
| BGT | bgt rs1, rs2, offset | 若 rs1 > rs2(有符号),跳转 | blt rs2, rs1, offset | RV32I / RV64I |
| BGTU | bgtu rs1, rs2, offset | 若 rs1 > rs2(无符号),跳转 | bltu rs2, rs1, offset | RV32I / RV64I |
| BLE | ble rs1, rs2, offset | 若 rs1 ≤ rs2(有符号),跳转 | bge rs2, rs1, offset | RV32I / RV64I |
| BLEU | bleu rs1, rs2, offset | 若 rs1 ≤ rs2(无符号),跳转 | bgeu rs2, rs1, offset | RV32I / RV64I |
3.7 跳转指令
跳转指令用于改变程序的执行流程,使程序能够跳转到代码中的其他位置执行

无条件跳转指令
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 指令集 |
|---|---|---|---|---|
| JAL | jal rd, offset | 跳转到 PC + offset,并将返回地址存入 rd | rd = PC + 4; PC += SignExt(offset << 1) | RV32I / RV64I |
| JALR | jalr rd, offset(rs1) | 跳转到 rs1 + offset,存入返回地址 | rd = PC + 4; PC = (rs1 + SignExt(offset)) & ~1 | RV32I / RV64I |
无条件跳转伪指令
| 伪指令 | 格式 | 功能描述 | 实际转换(基础指令) | 适用指令集 |
|---|---|---|---|---|
| J | j offset | 无条件跳转到 offset | jal x0, offset | RV32I / RV64I |
| JR | jr rs | 跳转到 rs 指向的地址 | jalr x0, 0(rs) | RV32I / RV64I |
| RET | ret | 从函数返回(跳转到 ra 地址) | jalr x0, 0(ra) | RV32I / RV64I |
3.8 同步指令
同步指令用于处理内存访问顺序控制,确保数据一致性和并发安全。
内存屏障指令
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|
| FENCE | fence pred, succ | 内存屏障(控制访存顺序) | 确保 pred 操作在 succ 操作前完成 (pred/succ 可以为 r(读)、w(写)、i(指令流)) | RV32I / RV64I |
| FENCE.I | fence.i | 指令流同步屏障 | 确保后续指令看到此前所有指令的修改(用于自修改代码) | RV32I / RV64I) |
3.9 环境指令
环境指令用于系统调用、调试、中断处理等特权级操作,通常需在特定权限模式下执行。
系统调用与异常处理指令
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|
| ECALL | ecall | 触发环境调用(系统调用/异常) | 根据当前模式跳转到异常处理程序 | RV32I / RV64I |
| EBREAK | ebreak | 触发断点异常(用于调试) | 进入调试模式或触发异常处理 | RV32I / RV64I |
中断返回指令
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|
| MRET | mret | 从机器模式异常返回 | PC = MEPC; Privilege = MPP | RV32I / RV64I |
| SRET | sret | 从监管者模式异常返回 | PC = SEPC; Privilege = SPP | RV32I / RV64I |
| URET | uret | 从用户模式异常返回 | PC = UEPC | RV32I / RV64I |
等待与暂停指令
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|
| WFI | wfi | 等待中断(暂停执行直至中断发生) | 暂停 CPU 直至中断或事件唤醒 | RV32I / RV64I ) |
3.10 控制状态寄存器指令
指令用于读写处理器的控制状态寄存器(如中断配置、计数器、特权模式设置等),支持原子操作和位操作,适用于系统编程和特权级管理。

CSR 读写指令
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|
| CSRRW | csrrw rd, csr, rs1 | 将 rs1 写入 CSR,原值存入 rd | t = CSR[csr]; CSR[csr] = rs1; rd = t | RV32I / RV64I |
| CSRRS | csrrs rd, csr, rs1 | 将 rs1 对应位设为 1,原值存入 rd | `t = CSR[csr]; CSR[csr] | = rs1; rd = t` |
| CSRRC | csrrc rd, csr, rs1 | 将 rs1 对应位清 0,原值存入 rd | t = CSR[csr]; CSR[csr] &= ~rs1; rd = t | RV32I / RV64I |
| CSRRWI | csrrwi rd, csr, imm | 将 5 位立即数写入 CSR | t = CSR[csr]; CSR[csr] = imm; rd = t | RV32I / RV64I |
| CSRRSI | csrrsi rd, csr, imm | 将立即数对应位置 1 | `t = CSR[csr]; CSR[csr] | = imm; rd = t` |
| CSRRCI | csrrci rd, csr, imm | 将立即数对应位清 0 | t = CSR[csr]; CSR[csr] &= ~imm; rd = t | RV32I / RV64I |
CSR 伪指令
| 伪指令 | 格式 | 功能描述 | 实际转换(基础指令) | 适用指令集 |
|---|---|---|---|---|
| CSRR | csrr rd, csr | 读取 CSR 的值到寄存器 | csrrs rd, csr, x0(读 CSR,不修改) | RV32I / RV64I |
| CSRW | csrw csr, rs | 将寄存器的值写入 CSR | csrrw x0, csr, rs(丢弃原值,仅写入) | RV32I / RV64I |
| CSRS | csrs csr, rs | 设置 CSR 中由 rs 指定的位 | csrrs x0, csr, rs(按位或,不保存结果) | RV32I / RV64I |
| CSRC | csrc csr, rs | 清除 CSR 中由 rs 指定的位 | csrrc x0, csr, rs(按位与取反,不保存结果) | RV32I / RV64I |
| CSRWI | csrwi csr, imm | 将 5 位立即数写入 CSR | csrrwi x0, csr, imm | RV32I / RV64I |
| CSRSI | csrsi csr, imm | 设置 CSR 中由立即数指定的位 | csrrsi x0, csr, imm | RV32I / RV64I |
| CSRCI | csrci csr, imm | 清除 CSR 中由立即数指定的位 | csrrci x0, csr, imm | RV32I / RV64I |
4 RVM指令集
RVM 扩展指令分为 乘法指令 和 除法/取余指令,支持有符号和无符号操作,并区分 RV32 和 RV64 的差异。

乘法指令
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|
| MUL | mul rd, rs1, rs2 | 乘法(低32/64位结果) | rd = (rs1 * rs2)[31:0](RV32)rd = rs1 * rs2(RV64) | RV32M / RV64M |
| MULH | mulh rd, rs1, rs2 | 有符号乘法(高32/64位结果) | rd = (rs1 * rs2)[63:32](RV32)rd = (rs1 * rs2)[127:64](RV64) | RV32M / RV64M |
| MULHU | mulhu rd, rs1, rs2 | 无符号乘法(高32/64位结果) | 同上,操作数为无符号数 | RV32M / RV64M |
| MULHSU | mulhsu rd, rs1, rs2 | 有符号-无符号乘法(高32/64位结果) | rs1 有符号,rs2 无符号 | RV32M / RV64M |
| MULW | mulw rd, rs1, rs2 | 32位乘法(结果符号扩展至64位) | rd = SignExt((rs1[31:0] * rs2[31:0])) | RV64M |
除法/取余指令
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|
| DIV | div rd, rs1, rs2 | 有符号除法(商) | rd = rs1 / rs2(向零舍入) | RV32M / RV64M |
| DIVU | divu rd, rs1, rs2 | 无符号除法(商) | rd = rs1 / rs2 | RV32M / RV64M |
| REM | rem rd, rs1, rs2 | 有符号取余(余数) | rd = rs1 % rs2(符号与 rs1 相同) | RV32M / RV64M |
| REMU | remu rd, rs1, rs2 | 无符号取余(余数) | rd = rs1 % rs2 | RV32M / RV64M |
| DIVW | divw rd, rs1, rs2 | 32位有符号除法(符号扩展至64位) | rd = SignExt((rs1[31:0] / rs2[31:0])) | RV64M |
| DIVUW | divuw rd, rs1, rs2 | 32位无符号除法(零扩展至64位) | rd = ZeroExt((rs1[31:0] / rs2[31:0])) | RV64M |
| REMW | remw rd, rs1, rs2 | 32位有符号取余(符号扩展至64位) | rd = SignExt((rs1[31:0] % rs2[31:0])) | RV64M |
| REMUW | remuw rd, rs1, rs2 | 32位无符号取余(零扩展至64位) | rd = ZeroExt((rs1[31:0] % rs2[31:0])) | RV64M |
5 RVFD指令集
5.1 访存指令
指令用于在内存和浮点寄存器(f0-f31)之间传输单精度(F 扩展)或双精度(D 扩展)浮点数据:

浮点加载和存储指令
| 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|
| FLW | flw fd, offset(rs1) | 从内存加载单精度浮点数到浮点寄存器 | fd = F32(Mem[rs1 + offset]) | RV32F / RV64F |
| FSW | fsw fs, offset(rs1) | 将单精度浮点数从浮点寄存器存入内存 | Mem[rs1 + offset] = F32(fs) | RV32F / RV64F |
| FLD | fld fd, offset(rs1) | 从内存加载双精度浮点数到浮点寄存器 | fd = F64(Mem[rs1 + offset]) | RV64D |
| FSD | fsd fs, offset(rs1) | 将双精度浮点数从浮点寄存器存入内存 | Mem[rs1 + offset] = F64(fs) | RV64D |
5.2 算术指令
算术指令用于执行各种数学运算,如加法、减法、乘法、除法等。当涉及到浮点数时,这些操作变得更为复杂,因为它们需要处理指数和尾数部分

基本算术指令
| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 加法 | FADD.S | fadd.s fd, fs1, fs2 | 单精度浮点加法 | fd = fs1 + fs2 | RV32F / RV64F |
| FADD.D | fadd.d fd, fs1, fs2 | 双精度浮点加法 | fd = fs1 + fs2 | RV64D | |
| 减法 | FSUB.S | fsub.s fd, fs1, fs2 | 单精度浮点减法 | fd = fs1 - fs2 | RV32F / RV64F |
| FSUB.D | fsub.d fd, fs1, fs2 | 双精度浮点减法 | fd = fs1 - fs2 | RV64D | |
| 乘法 | FMUL.S | fmul.s fd, fs1, fs2 | 单精度浮点乘法 | fd = fs1 * fs2 | RV32F / RV64F |
| FMUL.D | fmul.d fd, fs1, fs2 | 双精度浮点乘法 | fd = fs1 * fs2 | RV64D | |
| 除法 | FDIV.S | fdiv.s fd, fs1, fs2 | 单精度浮点除法 | fd = fs1 / fs2 | RV32F / RV64F |
| FDIV.D | fdiv.d fd, fs1, fs2 | 双精度浮点除法 | fd = fs1 / fs2 | RV64D | |
| 平方根 | FSQRT.S | fsqrt.s fd, fs1 | 单精度浮点平方根 | fd = sqrt(fs1) | RV32F / RV64F |
| FSQRT.D | fsqrt.d fd, fs1 | 双精度浮点平方根 | fd = sqrt(fs1) | RV64D | |
| 最小值 | FMIN.S | fmin.s fd, fs1, fs2 | 单精度浮点最小值 | fd = min(fs1, fs2) | RV32F / RV64F |
| FMIN.D | fmin.d fd, fs1, fs2 | 双精度浮点最小值 | fd = min(fs1, fs2) | RV64D | |
| 最大值 | FMAX.S | fmax.s fd, fs1, fs2 | 单精度浮点最大值 | fd = max(fs1, fs2) | RV32F / RV64F |
| FMAX.D | fmax.d fd, fs1, fs2 | 双精度浮点最大值 | fd = max(fs1, fs2) | RV64D |
5.3 RVFD 乘加指令
指令用于执行 乘加融合运算(Fused Multiply-Add, FMA),即在一个操作中完成乘法和加法,通常具有更高的精度和性能

| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 单精度乘加 | FMADD.S | fmadd.s fd, fs1, fs2, fs3 | 单精度浮点乘加 | fd = (fs1 * fs2) + fs3 | RV32F / RV64F |
| 单精度乘减 | FMSUB.S | fmsub.s fd, fs1, fs2, fs3 | 单精度浮点乘减 | fd = (fs1 * fs2) - fs3 | RV32F / RV64F |
| 单精度负乘加 | FNMADD.S | fnmadd.s fd, fs1, fs2, fs3 | 单精度浮点负乘加 | fd = -((fs1 * fs2) + fs3) | RV32F / RV64F |
| 单精度负乘减 | FNMSUB.S | fnmsub.s fd, fs1, fs2, fs3 | 单精度浮点负乘减 | fd = -((fs1 * fs2) - fs3) | RV32F / RV64F |
| 双精度乘加 | FMADD.D | fmadd.d fd, fs1, fs2, fs3 | 双精度浮点乘加 | fd = (fs1 * fs2) + fs3 | RV64D |
| 双精度乘减 | FMSUB.D | fmsub.d fd, fs1, fs2, fs3 | 双精度浮点乘减 | fd = (fs1 * fs2) - fs3 | RV64D |
| 双精度负乘加 | FNMADD.D | fnmadd.d fd, fs1, fs2, fs3 | 双精度浮点负乘加 | fd = -((fs1 * fs2) + fs3) | RV64D |
| 双精度负乘减 | FNMSUB.D | fnmsub.d fd, fs1, fs2, fs3 | 双精度浮点负乘减 | fd = -((fs1 * fs2) - fs3) | RV64D |
5.4 RVFD传送指令
指令用于在 浮点寄存器 和 整数寄存器 之间传输数据,或在不同浮点寄存器之间复制数据

| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 浮点到整数 | FMV.X.S | fmv.x.s rd, fs1 | 将单精度浮点数转为整数表示 | rd = fs1(按位复制) | RV32F / RV64F |
| 浮点到整数 | FMV.X.D | fmv.x.d rd, fs1 | 将双精度浮点数转为整数表示 | rd = fs1(按位复制) | RV64D |
| 整数到浮点 | FMV.S.X | fmv.s.x fd, rs1 | 将整数表示转为单精度浮点数 | fd = rs1(按位复制) | RV32F / RV64F |
| 整数到浮点 | FMV.D.X | fmv.d.x fd, rs1 | 将整数表示转为双精度浮点数 | fd = rs1(按位复制) | RV64D |
5.5 RVFD 转换指令
分两类归纳:浮点寄存器间传送 和 浮点与整数寄存器间传送,涵盖符号操作、位模式复制及特殊值处理

浮点与整数之间的转换
| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 浮点 → 整数 | FCVT.W.S | fcvt.w.s rd, fs1 | 单精度浮点转为 32 位有符号整数 | rd = (int32_t)fs1 | RV32F / RV64F |
| FCVT.WU.S | fcvt.wu.s rd, fs1 | 单精度浮点转为 32 位无符号整数 | rd = (uint32_t)fs1 | RV32F / RV64F | |
| FCVT.L.S | fcvt.l.s rd, fs1 | 单精度浮点转为 64 位有符号整数 | rd = (int64_t)fs1 | RV64F | |
| FCVT.LU.S | fcvt.lu.s rd, fs1 | 单精度浮点转为 64 位无符号整数 | rd = (uint64_t)fs1 | RV64F | |
| FCVT.W.D | fcvt.w.d rd, fs1 | 双精度浮点转为 32 位有符号整数 | rd = (int32_t)fs1 | RV64D | |
| FCVT.WU.D | fcvt.wu.d rd, fs1 | 双精度浮点转为 32 位无符号整数 | rd = (uint32_t)fs1 | RV64D | |
| FCVT.L.D | fcvt.l.d rd, fs1 | 双精度浮点转为 64 位有符号整数 | rd = (int64_t)fs1 | RV64D | |
| FCVT.LU.D | fcvt.lu.d rd, fs1 | 双精度浮点转为 64 位无符号整数 | rd = (uint64_t)fs1 | RV64D | |
| 整数 → 浮点 | FCVT.S.W | fcvt.s.w fd, rs1 | 32 位有符号整数转为单精度浮点 | fd = (float)rs1 | RV32F / RV64F |
| FCVT.S.WU | fcvt.s.wu fd, rs1 | 32 位无符号整数转为单精度浮点 | fd = (float)rs1 | RV32F / RV64F | |
| FCVT.S.L | fcvt.s.l fd, rs1 | 64 位有符号整数转为单精度浮点 | fd = (float)rs1 | RV64F | |
| FCVT.S.LU | fcvt.s.lu fd, rs1 | 64 位无符号整数转为单精度浮点 | fd = (float)rs1 | RV64F | |
| FCVT.D.W | fcvt.d.w fd, rs1 | 32 位有符号整数转为双精度浮点 | fd = (double)rs1 | RV64D | |
| FCVT.D.WU | fcvt.d.wu fd, rs1 | 32 位无符号整数转为双精度浮点 | fd = (double)rs1 | RV64D | |
| FCVT.D.L | fcvt.d.l fd, rs1 | 64 位有符号整数转为双精度浮点 | fd = (double)rs1 | RV64D | |
| FCVT.D.LU | fcvt.d.lu fd, rs1 | 64 位无符号整数转为双精度浮点 | fd = (double)rs1 | RV64D |
浮点精度之间的转换
| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 单精度 ↔ 双精度 | FCVT.S.D | fcvt.s.d fd, fs1 | 双精度浮点转为单精度浮点 | fd = (float)fs1 | RV64D |
| 单精度 ↔ 双精度 | FCVT.D.S | fcvt.d.s fd, fs1 | 单精度浮点转为双精度浮点 | fd = (double)fs1 | RV64D |
5.6 RVFD 符号注入指令
指令用于将 整数立即数 或 整数寄存器值 注入到浮点寄存器中,通常用于快速构造浮点常数或特殊值(如 NaN、无穷大)

单精度浮点注入指令
| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 符号复制 | FSGNJ.S | fsgnj.s fd, fs1, fs2 | 复制数值,符号位取自 fs2 | fd = {fs2[31], fs1[30:0]} | RV32F / RV64F |
| 符号取反 | FSGNJN.S | fsgnjn.s fd, fs1, fs2 | 复制数值,符号位取反自 fs2 | fd = {~fs2[31], fs1[30:0]} | RV32F / RV64F |
| 符号取绝对值 | FSGNJX.S | fsgnjx.s fd, fs1, fs2 | 复制数值,符号位异或(取绝对值) | fd = {fs1[31] ^ fs2[31], fs1[30:0]} | RV32F / RV64F |
双精度浮点注入指令
| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 符号复制 | FSGNJ.D | fsgnj.d fd, fs1, fs2 | 复制数值,符号位取自 fs2 | fd = {fs2[63], fs1[62:0]} | RV64D |
| 符号取反 | FSGNJN.D | fsgnjn.d fd, fs1, fs2 | 复制数值,符号位取反自 fs2 | fd = {~fs2[63], fs1[62:0]} | RV64D |
| 符号取绝对值 | FSGNJX.D | fsgnjx.d fd, fs1, fs2 | 复制数值,符号位异或(取绝对值) | fd = {fs1[63] ^ fs2[63], fs1[62:0]} | RV64D |
伪指令
| 指令类型 | 伪指令 | 格式 | 功能描述 | 实际转换(基础指令) | 适用指令集 |
|---|---|---|---|---|---|
| 单精度浮点注入 | FABS.S | fabs.s fd, fs | 单精度浮点取绝对值 | fsgnjx.s fd, fs, fs | RV32F / RV64F |
| FMV.S | fmv.s fd, fs | 单精度浮点复制 | fsgnj.s fd, fs, fs | RV32F / RV64F | |
| FNEG.S | fneg.s fd, fs | 单精度浮点取反 | fsgnjn.s fd, fs, fs | RV32F / RV64F |
| 指令类型 | 伪指令 | 格式 | 功能描述 | 实际转换(基础指令) | 适用指令集 |
|---|---|---|---|---|---|
| 双精度浮点注入 | FABS.D | fabs.d fd, fs | 双精度浮点取绝对值 | fsgnjx.d fd, fs, fs | RV64D |
| FMV.D | fmv.d fd, fs | 双精度浮点复制 | fsgnj.d fd, fs, fs | RV64D | |
| FNEG.D | fneg.d fd, fs | 双精度浮点取反 | fsgnjn.d fd, fs, fs | RV64D |
5.7 RVFD 比较指令
指令用于比较两个浮点数的值,并将比较结果写入整数寄存器,支持 相等、小于 和 小于等于 三种比较操作

| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 相等比较 | FEQ.S | feq.s rd, fs1, fs2 | 单精度浮点相等比较 | rd = (fs1 == fs2) ? 1 : 0 | RV32F / RV64F |
| FEQ.D | feq.d rd, fs1, fs2 | 双精度浮点相等比较 | rd = (fs1 == fs2) ? 1 : 0 | RV64D | |
| 小于比较 | FLT.S | flt.s rd, fs1, fs2 | 单精度浮点小于比较 | rd = (fs1 < fs2) ? 1 : 0 | RV32F / RV64F |
| FLT.D | flt.d rd, fs1, fs2 | 双精度浮点小于比较 | rd = (fs1 < fs2) ? 1 : 0 | RV64D | |
| 小于等于比较 | FLE.S | fle.s rd, fs1, fs2 | 单精度浮点小于等于比较 | rd = (fs1 <= fs2) ? 1 : 0 | RV32F / RV64F |
| FLE.D | fle.d rd, fs1, fs2 | 双精度浮点小于等于比较 | rd = (fs1 <= fs2) ? 1 : 0 | RV64D |
5.8 RVFD 分类指令
指令用于检查浮点数的类别(如正无穷、负零、NaN 等),并将结果写入整数寄存器,适用于浮点数的异常处理和特殊值检测

| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 浮点分类 | 单精度分类 | fclass.s rd, fs1 | 单精度浮点分类 | rd = classify(fs1) | RV32F / RV64F |
| 浮点分类 | 双精度分类 | fclass.d rd, fs1 | 双精度浮点分类 | rd = classify(fs1) | RV64D |
5.9 RVFD 配置指令
指令用于配置和管理浮点单元的状态,包括 舍入模式、异常标志 和 浮点控制状态寄存器(fcsr) 的操作
| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 浮点控制状态寄存器(fcsr)操作 | |||||
| 读取 fcsr | FRCSR | frcsr rd | 读取 fcsr 的值到整数寄存器 | rd = fcsr | RV32F / RV64F |
| 写入 fcsr | FSCSR | fscsr rd, rs | 将整数寄存器的值写入 fcsr | fcsr = rs | RV32F / RV64F |
| 交换 fcsr | FSRCS | fscsr rd, rs | 交换 fcsr 和整数寄存器的值 | t = fcsr; fcsr = rs; rd = t | RV32F / RV64F |
| 舍入模式配置 | |||||
| 读取舍入模式 | FRRM | frrm rd | 读取舍入模式到整数寄存器 | rd = fcsr[7:5] | RV32F / RV64F |
| 写入舍入模式 | FSRM | fsrm rd, rs | 将整数寄存器的值写入舍入模式 | fcsr[7:5] = rs[2:0] | RV32F / RV64F |
| 交换舍入模式 | FSRRM | fsrrm rd, rs | 交换舍入模式和整数寄存器的值 | t = fcsr[7:5]; fcsr[7:5] = rs[2:0]; rd = t | RV32F / RV64F |
| 异常标志操作 | |||||
| 读取异常标志 | FFLAGS | fflags rd | 读取异常标志到整数寄存器 | rd = fcsr[4:0] | RV32F / RV64F |
| 写入异常标志 | FSFLAGS | fsflags rd, rs | 将整数寄存器的值写入异常标志 | fcsr[4:0] = rs[4:0] | RV32F / RV64F |
| 交换异常标志 | FSRFLAGS | fsrflags rd, rs | 交换异常标志和整数寄存器的值 | t = fcsr[4:0]; fcsr[4:0] = rs[4:0]; rd = t | RV32F / RV64F |
6 RVA指令集
RVA(Atomic Operations)扩展为 RISC-V 提供了硬件支持的原子操作指令,用于在多线程或多核环境中实现 原子内存访问 和 同步操作,确保数据一致性和并发安全。

加载保留与条件存储指令
| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 加载保留 | LR.W | lr.w rd, (rs1) | 加载保留(原子加载字,标记内存地址) | rd = Mem[rs1]; Reserve rs1 | RV32A / RV64A |
| LR.D | lr.d rd, (rs1) | 加载保留(原子加载双字) | rd = Mem[rs1]; Reserve rs1 | RV64A | |
| 条件存储 | SC.W | sc.w rd, rs2, (rs1) | 条件存储(若地址未被修改,存储字) | if (Reserve rs1 still valid) { Mem[rs1] = rs2; rd = 0 } else { rd = 1 } | RV32A / RV64A |
| SC.D | sc.d rd, rs2, (rs1) | 条件存储(若地址未被修改,存储双字) | if (Reserve rs1 still valid) { Mem[rs1] = rs2; rd = 0 } else { rd = 1 } | RV64A |
原子内存操作指令
| 指令类型 | 指令 | 格式 | 功能描述 | 操作(伪代码) | 适用指令集 |
|---|---|---|---|---|---|
| 原子加 | AMOADD.W | amoadd.w rd, rs2, (rs1) | 原子加并返回原值 | rd = Mem[rs1]; Mem[rs1] += rs2 | RV32A / RV64A |
| AMOADD.D | amoadd.d rd, rs2, (rs1) | 原子加并返回原值(双字) | rd = Mem[rs1]; Mem[rs1] += rs2 | RV64A | |
| 原子交换 | AMOSWAP.W | amoswap.w rd, rs2, (rs1) | 原子交换并返回原值 | rd = Mem[rs1]; Mem[rs1] = rs2 | RV32A / RV64A |
| AMOSWAP.D | amoswap.d rd, rs2, (rs1) | 原子交换并返回原值(双字) | rd = Mem[rs1]; Mem[rs1] = rs2 | RV64A | |
| 原子按位与 | AMOAND.W | amoand.w rd, rs2, (rs1) | 原子按位与并返回原值 | rd = Mem[rs1]; Mem[rs1] &= rs2 | RV32A / RV64A |
| AMOAND.D | amoand.d rd, rs2, (rs1) | 原子按位与并返回原值(双字) | rd = Mem[rs1]; Mem[rs1] &= rs2 | RV64A | |
| 原子按位或 | AMOOR.W | amoor.w rd, rs2, (rs1) | 原子按位或并返回原值 | `rd = Mem[rs1]; Mem[rs1] | = rs2` |
| AMOOR.D | amoor.d rd, rs2, (rs1) | 原子按位或并返回原值(双字) | `rd = Mem[rs1]; Mem[rs1] | = rs2` | |
| 原子按位异或 | AMOXOR.W | amoxor.w rd, rs2, (rs1) | 原子按位异或并返回原值 | rd = Mem[rs1]; Mem[rs1] ^= rs2 | RV32A / RV64A |
| AMOXOR.D | amoxor.d rd, rs2, (rs1) | 原子按位异或并返回原值(双字) | rd = Mem[rs1]; Mem[rs1] ^= rs2 | RV64A | |
| 原子最大值 | AMOMAX.W | amomax.w rd, rs2, (rs1) | 原子有符号最大值并返回原值 | rd = Mem[rs1]; Mem[rs1] = max(rd, rs2) | RV32A / RV64A |
| AMOMAX.D | amomax.d rd, rs2, (rs1) | 原子有符号最大值并返回原值(双字) | rd = Mem[rs1]; Mem[rs1] = max(rd, rs2) | RV64A | |
| 原子无符号最大值 | AMOMAXU.W | amomaxu.w rd, rs2, (rs1) | 原子无符号最大值并返回原值 | rd = Mem[rs1]; Mem[rs1] = maxu(rd, rs2) | RV32A / RV64A |
| AMOMAXU.D | amomaxu.d rd, rs2, (rs1) | 原子无符号最大值并返回原值(双字) | rd = Mem[rs1]; Mem[rs1] = maxu(rd, rs2) | RV64A | |
| 原子最小值 | AMOMIN.W | amomin.w rd, rs2, (rs1) | 原子有符号最小值并返回原值 | rd = Mem[rs1]; Mem[rs1] = min(rd, rs2) | RV32A / RV64A |
| AMOMIN.D | amomin.d rd, rs2, (rs1) | 原子有符号最小值并返回原值(双字) | rd = Mem[rs1]; Mem[rs1] = min(rd, rs2) | RV64A | |
| 原子无符号最小值 | AMOMINU.W | amominu.w rd, rs2, (rs1) | 原子无符号最小值并返回原值 | rd = Mem[rs1]; Mem[rs1] = minu(rd, rs2) | RV32A / RV64A |
| AMOMINU.D | amominu.d rd, rs2, (rs1) | 原子无符号最小值并返回原值(双字) | rd = Mem[rs1]; Mem[rs1] = minu(rd, rs2) | RV64A |
上面列举了RISC-V指令集,但实际上上面列举的指令集我很多也没用过,是按照spec总结了下,如有错误或者遗漏,还请各位大佬评论区指出。
参考
riscv-spec-20240411.pdf
一起学RISC-V汇编第5讲之常用指令及伪指令列表
RISC-V 常用汇编指令
相关文章:
RISC-V汇编学习(三)—— RV指令集
有了前两节对于RISC-V汇编、寄存器、汇编语法等的认识,本节开始介绍RISC-V指令集和伪指令。 前面说了RISC-V的模块化特点,是以RV32I为作为ISA的核心模块,其他都是要基于此为基础,可以这样认为:RISC-V ISA 基本整数指…...
java 重点知识 — JVM存储模块与类加载器
1 jvm主要模块 方法区 存储了由类加载器从.class文件中解析的类的元数据(类型信息、域信息、方法信息)及运行时常量池(引用符号及字面量)。 所有线程共享;内存不要求连续,可扩展,可能发生垃圾回…...
WPF有哪些使用率高的框架
架构类库 Community Toolkit MVVMMVVM Light UI类库 MahApps.MetroMaterial Design In XAML Toolkit 图标类库 MahApps.Metro.IconPacks...
idea中使用DeepSeek让编程更加便捷
IDEA中使用DeepSeek让编程更加便捷 对于开发者来说,IDEA(IntelliJ IDEA)是一款强大的开发工具。但你是否知道,通过安装DeepSeek这款插件,可以让你的编程体验更上一层楼?今天,我们就来聊聊如何在…...
创建Electron35 + vue3 + electron-builder项目,有很过坑,记录过程
环境: node v20.18.0 npm 11.1.0 用到的所有依赖: "dependencies": {"core-js": "^3.8.3","vue": "^3.2.13","vue-router": "^4.5.0"},"devDependencies": {"ba…...
elasticsearch是哪家的
Elasticsearch:数据搜索与分析的领航者 在当今这个信息爆炸的时代,快速且准确地处理海量数据成为了众多企业和组织追求的目标。而Elasticsearch正是在这个背景下脱颖而出的一款强大的开源搜索引擎。它是由位于美国加利福尼亚州的Elastic公司所开发和维护…...
nginx基础http基础
目录 nginx简介正向代理&反向代理正向代理反向代理What Is a Reverse Proxy Server? High-Performance Load Balancing (负载均衡)Problem(问题)Solution(解决方案)常见负载均衡算法Round Robin(轮询)…...
5. MySQL 存储引擎(详解说明)
5. MySQL 存储引擎(详解说明) 文章目录 5. MySQL 存储引擎(详解说明)1. 查看存储引擎2. 设置系统默认的存储引擎3. 设置表的存储引擎3.1 创建表时指定存储引擎3.2 修改表的存储引擎 4. 引擎介绍4.1 InnoDB 引擎:具备外键支持功能的事务存储引擎4.2 MyISAM 引擎&…...
基于LabVIEW的伺服阀高频振动测试闭环控制系统
为实现伺服阀在设定位置上下快速移动(1kHz控制频率)的振动测试目标,需构建基于LabVIEW的闭环控制系统。系统需满足高速数据采集、实时控制算法(如PID或自适应控制)、高精度电流驱动及传感器反馈处理等需求。结合用户提…...
97.在 Vue 3 中使用 OpenLayers 根据两行根数 (TLE) 计算并显示卫星轨迹(EPSG:3857)
前言 在许多卫星应用场景中,我们需要 基于 TLE(Two-Line Element Set, 两行根数)计算卫星轨迹,并在地图上进行可视化。本文将使用 Vue 3 OpenLayers satellite.js,实现 实时计算卫星轨迹,并在地图上动态更…...
Android Coil总结
文章目录 Android Coil总结概述添加依赖用法基本用法占位图变形自定义ImageLoader取消加载协程支持缓存清除缓存监听 简单封装 Android Coil总结 概述 Coil 是一个用于 Android 的 Kotlin 图像加载库,旨在简化图像加载和显示的过程。它基于 Kotlin 协程࿰…...
fastjson漏洞#不出网#原理#流量特征
原理 本质是java的反序列化漏洞,由于引进了自动检测类型的(autotype)功能,fastjson在对json字符串反序列化的时候,会读取type内容,会试图将json内容反序列化成这个对象,并调用这个类的setter方…...
云计算:虚拟化、容器化与云存储技术详解
在上一篇中,我们深入探讨了网络安全的核心技术,包括加密、认证和防火墙,并通过实际案例和细节帮助读者全面理解这些技术的应用和重要性。今天,我们将转向一个近年来迅速发展的领域——云计算。云计算通过提供按需访问的计算资源,彻底改变了IT基础设施的构建和管理方式。本…...
使用 marked.min.js 实现 Markdown 编辑器 —— 我的博客后台选择之旅
最近,我决定为个人博客后台换一个编辑器。之前的富文本编辑器虽然功能齐全,但生成的 HTML 代码繁杂,维护起来非常麻烦。为了追求更简洁高效的写作体验,我开始研究 Markdown 编辑器,并最终选择了 marked.min.js。 1. 传…...
Linux系统基于ARM平台的LVGL移植
软硬件介绍:Ubuntu 20.04 ARM 和(Cortex-A53架构)开发板 基本原理 LVGL图形库是支持使用Linux系统的Framebuffer帧缓冲设备实现的,如果想要实现在ARM开发板上运行LVGL图形库,那么就需要把LVGL图形库提供的关于帧缓冲设…...
LeetCode 2070.每一个查询的最大美丽值:排序 + 二分查找
【LetMeFly】2070.每一个查询的最大美丽值:排序 二分查找 力扣题目链接:https://leetcode.cn/problems/most-beautiful-item-for-each-query/ 给你一个二维整数数组 items ,其中 items[i] [pricei, beautyi] 分别表示每一个物品的 价格 和…...
电力场景绝缘子缺陷分割数据集labelme格式1585张4类别
数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数):1585 标注数量(json文件个数):1585 标注类别数:4 标注类别名称:["broken part","broken insulat…...
【计算机网络】深入解析 HTTP 协议的概念、工作原理和通过 Fiddler 抓包查看 HTTP 请求/响应的协议格式
网络原理— HTTP 1. 什么是HTTP? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议: HTTP 往往是基于传输层的 TCP 协议实现的 (HTTP1.0,HTTP1.1,HTTP2.0 均为TCP,HTTP3基于UDP实现) 我们平时打开一个网站,就是通过HTTP协议来…...
IPFS:下一代互联网传输协议
IPFS:下一代互联网传输协议 1. 引言2. IPFS概述3. IPFS的核心优势3.1 去中心化3.2 高效性3.3 安全性3.4 持久性3.5 可扩展性 4. IPFS的工作原理4.1 内容寻址4.2 分布式哈希表(DHT)4.3 文件分块4.4 版本控制4.5 网络协议 5. IPFS的应用场景5.1…...
线上接口tp99突然升高如何排查?
当线上接口的 TP99 突然升高时,意味着该接口在 99% 的情况下响应时间变长,这可能会严重影响系统的性能和用户体验。可以按照下面的步骤进行排查。这里我们先说明一下如何计算tp99:监控系统计算 TP99(第 99 百分位数的响应时间&…...
SpringBoot优雅关机,监听关机事件,docker配置
Spring Boot 提供了多种方法来实现优雅停机(Graceful Shutdown),这意味着在关闭应用程序之前,它会等待当前正在处理的请求完成,并且不再接受新的请求。 一、优雅停机的基本概念 优雅停机的主要步骤如下: …...
在【k8s】中部署Jenkins的实践指南
🐇明明跟你说过:个人主页 🏅个人专栏:《Kubernetes航线图:从船长到K8s掌舵者》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Jenkins简介 2、k8s简介 3、什么在…...
Unity DOTS从入门到精通之 C# Job System
文章目录 前言安装 DOTS 包C# 任务系统Mono 环境DOTS 环境运行作业NativeContainer 前言 作为 DOTS 教程,我们将创建一个旋转立方体的简单程序,并将传统的 Unity 设计转换为 DOTS 设计。 Unity 2022.3.52f1Entities 1.3.10 安装 DOTS 包 要安装 DOTS…...
Spring Boot 本地缓存工具类设计与实现
在 Spring Boot 应用中,缓存是提升性能的重要手段之一。为了更方便地使用缓存,我们可以设计一套通用的本地缓存工具类,封装常见的缓存操作,简化开发流程。本文将详细介绍如何设计并实现一套 Spring Boot 本地缓存工具类࿰…...
【Godot4.4】浅尝Godot中的MVC
概述 基于一个Unity的视频。学习了一下基本的MVC概念,并尝试在Godot中实现了一下。 原始的MVC: Godot中的MVC: Model、View和Controller各自应该实现的功能如下: Model: 属性(数据字段)数据存取方法数据更新信号 View: 控…...
如何解决前端的竞态问题
前端的竞态问题通常是指多个异步操作的响应顺序与发起顺序不一致,导致程序出现不可预测的结果。这种问题在分页、搜索、选项卡切换等场景中尤为常见。以下是几种常见的解决方法: 1. 取消过期请求 当用户发起新的请求时,取消之前的请求&…...
Elasticsearch为索引设置自动时间戳,ES自动时间戳
文章目录 0、思路1、配置 ingest pipeline2、在索引映射中启用_source字段的时间戳3、使用 index template 全局设置时间戳4、写入测试数据5、验证结果6、总结 在使用 Elasticsearch 进行数据存储和检索时,时间戳字段是一个非常重要的组成部分。它可以帮助我们追踪数…...
计算机网络:计算机网络的组成和功能
计算机网络的组成: 计算机网络的工作方式: 计算机网络的逻辑功能; 总结: 计算机网络的功能: 1.数据通信 2.资源共享 3.分布式处理:计算机网络的分布式处理是指将计算任务分散到网络中的多个节点(计算机或设备&…...
FPGA设计时序约束用法大全保姆级说明
目录 一、序言 二、时序约束概览 2.1 约束五大类 2.2 约束功能简述 2.3 跨时钟域约束 三、时序约束规范 3.1 时序约束顺序 3.2 约束的优先级 四、约束示例 4.1 设计代码 4.2 时序结果 4.2.1 create_clock 4.2.2 create_generated_clock 4.2.3 Rename_Auto-Derive…...
云服务运维智能时代:阿里云操作系统控制台
阿里云操作系统控制台 引言需求介绍操作系统使用实例获得的帮助与提升建议 引言 阿里云操作系统控制台是一款创新型云服务器运维工具,专为简化用户的运维工作而设计。它采用智能化和可视化的方式,让运维变得更加高效、直观。借助AI技术,控制…...
