lhu
lyszt.net 更详细地介绍了 lhu 和其他 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
描述
lhu 从内存中读取一个半字(16 位,即 2 字节),并将其视为无符号数。它与 lh 配对,两者的区别在于如何填充目标寄存器的高半部分。两者都以相同的寻址方式读取 16 位。半字和寻址形式在 lh 页面中介绍。lhu 的形式如下所示。
lhu rd, offset(rs1)
寄存器保存 32 位,因此 16 位加载必须填充高 16 位。lh 将符号位复制到这些位中,从而保持负数为负数。lhu 用 0 填充它们,称为零扩展,因此结果始终为非负数,从 0 到 65535。名称中的 u 表示无符号读取。
使用哪一个由数据决定。对于可能为负的值选择 lh,对于永远不会为负的值选择 lhu。用 lhu 加载位模式 0xFFFF 得到 65535,而用 lh 加载相同的位得到 -1。
RISC-V 手册将 lhu 定义为从内存加载 16 位值,并在将其存储到 rd 之前零扩展到 32 位。有效地址是寄存器 rs1 加上符号扩展的 12 位偏移量。
大多数 16 位数据是无符号的。某些文本编码中的字符代码、网络数据中的端口号和校验和、16 位像素格式以及文件格式中的长度字段都是例子。一旦最高位被置位,符号扩展对其中任何一个都会给出错误的值,因此 lhu 是正确的加载。半字之间相隔 2 字节,因此遍历它们的循环将地址移动 2。
示例
.data val: .half 0xffff .text la t0, val lhu t1, 0(t0) # t1 = 65535 (zero-extended)
