lbu

lbu

RISC-V 汇编 参考

lyszt.net 更详细地介绍了 lbu 和其他 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

描述

lbu 从内存中读取一个字节(8 位)作为无符号值。它与 lb 配对,两者仅在如何填充寄存器其余部分上有所不同。两者都使用相同的寻址方式读取一个字节。lb 页面涵盖了字节和寻址形式。lbu 的形式如下所示。

lbu rd, offset(rs1)

一个寄存器保存 32 位,因此 1 字节的加载会留下 24 位需要填充。lb 将该字节的最高位复制到这些位中,这就是符号扩展,可能会产生负数。lbu 用 0 填充它们,因此结果始终在 0 到 255 之间。u 代表无符号读取。

文本加载通常使用 lbu。字符代码是无符号的,许多字符的最高位被置位,包括带重音符号的字母和各种符号。进行符号扩展的 lb 会使它们变为负数并破坏比较。标准文本循环使用 lbu。它加载一个字节,检查它是否为零(这标志着文本的结束),处理它并将地址加 1。

RISC-V 手册将 lb 和 lbu 定义为半字加载的 8 位版本,其有效地址相同,为寄存器 rs1 加上符号扩展的 12 位偏移量。内存按字节寻址,因此每个地址对应一个字节。

lbu 也适用于其他字节数据,包括图像中的颜色通道、原始数据缓冲区和解释器中的指令字节。以这种方式加载的字节没有符号需要处理,因此当从单个字节重建更大的值时,它们可以直接与移位和 OR 结合使用。仅当 8 位数据是有符号时才使用 lb。

示例

.data
val: .byte 0xff
.text
la t0, val
lbu t1, 0(t0)   # t1 = 255 (zero-extended)