sh
lyszt.net 更详细地介绍了 sh 和其他 RISC-V 指令。
编码格式
R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode
描述
sh 将一个半字(16 位或 2 字节)写入内存。它与 lh 和 lhu 加载相匹配,存储比 sw 存储完整字更窄的大小。格式如下所示。它取源寄存器 rs2 中的值,并将其最低 16 位写入基址寄存器 rs1 中的地址加上偏移量处。布局与 sw 匹配,源寄存器在前。
sh rs2, offset(rs1)
寄存器保存 32 位,而只存储 16 位,因此 sh 保留最低 16 位并丢弃高 16 位。存储没有有符号或无符号的选择。该选择属于加载,其中窄值必须扩展以填充寄存器,缺失的位需要规则。存储会收窄值,保留低位是唯一合理的行为。如果寄存器保存的值对于 16 位来说太大,多余的位会丢失且没有警告,因此在存储前请检查范围。
RISC-V 手册说 sh 将寄存器 rs2 的低 16 位存储到 rs1 的地址加上符号扩展的 12 位偏移量处的内存。偶数地址处的半字存储是自然对齐的,永远不会引发对齐错误。对非自然对齐地址的存储行为由执行环境定义,手册说它可能运行得极其缓慢。
sh 写入 lh 和 lhu 读回的每一种 16 位格式,例如音频样本、16 位像素数据和半字数组。常见的模式是读取、修改和写入。用 lhu 加载一个半字,在寄存器中调整它,然后用 sh 存回。只有目标 2 字节发生变化,周围的字节保持原样。半字相隔 2 字节,因此循环将地址移动 2。
示例
la t0, slot li t1, -5 sh t1, 0(t0) # memory at slot now holds the low 16 bits of -5
