首页/指令库/逻辑左移
SLL

RISC-V SLL 指令详解

指令手册R-type

将rs1按rs2的低log2(XLEN)位逻辑左移(低位补零),结果写入rd

指令语法

sll rd, rs1, rs2
操作数说明
rd:选择 x0–x31;写入 x0 被丢弃。rs1:提供写回前的源值。
rs2:RV32 只用低 5 位、RV64 只用低 6 位提供移位量。
逻辑左移低位补零,丢弃超出 XLEN 的高位。
RV32IRV64I算术运算移位

指令行为说明

SLL 指令采用 R-type 格式,将 rs1 按 rs2 低 log2(XLEN) 位给出的移位量逻辑左移:RV32 使用 rs2[4:0],RV64 使用 rs2[5:0]。左侧移出的高位丢弃,低位补 0,结果按 XLEN 截断后写入 rd。opcode=0110011,funct3=001,funct7=0000000。

SLL 指令解析与执行动画

从机器码字段解析开始,依次展示操作数读取、该指令专属语义计算和 ISA 可见状态更新。

rd
rs1
rs2
sll
,
,
执行环境

本例使用固定寄存器初值和初始 PC=0x2000;取指成功,没有异步中断或额外扩展检查。异常分支只显示普通提交停止,陷入后的 PC 和处理程序状态由 EEI 决定。

t1(x6)
0x00000014
sp(x2)
0x00000002
31..25
24..20
19..15
14..12
11..7
6..0
0000000
funct7
00010
rs2
00110
rs1
001
funct3
00101
rd
0110011
opcode
执行数据路径
instruction
0x002312B3
opcode
0110011 -> OP
funct3
001 -> SLL
funct7
0000000 -> base ALU op
rd / rs1 / rs2
t0(x5) / t1(x6) / sp(x2)
shamt
rs2 low 5 bits -> 2
ALU
尚未计算
x5
t0(x5) = 0x00003001; pc = 0x00002000
当前步骤

概念步骤:拿到 32-bit 指令编码

机器码按当前指令格式切成字段,动画从 encoding/decode 开始。

encoding: 0x002312B3
syntax : sll t0(x5), t1(x6), sp(x2)
待提交结果: 尚未计算
当前架构状态
t0(x5) = 0x00003001; pc = 0x00002000

该动画展示 ISA 可见的解码和状态变化,不表示任何特定 CPU 的流水线、缓存、预测或时序实现。

快速理解与检索要点

SLL 从 rs2 的低 log2(XLEN) 位取得动态移位量,把 rs1 逻辑左移,低位补 0,高位溢出丢弃,结果写入 rd。

opcode=0110011 选择 OP 类;funct3=001 且 funct7=0000000 选择 SLL。
寄存器移位量由 XLEN 决定:RV32 使用低 5 位,RV64 使用低 6 位。

常见使用场景

位操作与移位

RV32I/RV64I,x6=20、x7=2:sll x5, x6, x7 得到 x5=80(0x50);只保留低 XLEN 位。

使用前检查清单

语法检查
  • 寄存器操作数选择 x0–x31 或其 ABI 名称;源使用写回前的值。
  • rd、rs1、rs2 均为寄存器字段,没有立即数操作数。
语义检查
  • 将rs1按rs2的低log2(XLEN)位逻辑左移(低位补零),结果写入rd
  • x0 始终为零,写入丢弃;整数计算不引发算术异常。

容易混淆 / 常见误区

移位量只取 rs2 的低 log2(XLEN) 位;rs2 的其它高位不参与移位量。
SLL 是逻辑左移,低位补 0;左移溢出的高位直接丢弃,不产生算术异常或标志位。

常见问题

SLL 的移位量为什么不是整个 rs2?

官方基础整数语义规定寄存器移位只取 rs2 的低 log2(XLEN) 位;因此 RV32 只看 5 位,RV64 只看 6 位。

SLL 和 SLLI 怎么选?

移位量运行时在寄存器中时用 SLL;移位量是可编码常数时用 SLLI。