lb
lyszt.net 更详细地介绍了 lb 和其他 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
描述
lb 从内存中读取一个字节,这是加载操作能获取的最小单位。内存由字节构成,每个字节是 8 位,一个地址标识一个字节。lw 读取 4 个字节,lh 读取 2 个,lb 读取 1 个。它使用与其他加载指令相同的寻址方式:基址寄存器加偏移量(参见 lw 页面)。其形式如下所示。
lb rd, offset(rs1)
一个寄存器保存 32 位,一个字节保存 8 位,因此高 24 位需要一个值。lb 进行符号扩展:它将该字节的最高位复制到所有高位中,从而将值保留为有符号数。一个保存 -5 的字节到达时会变成 32 位的 -5。
有符号/无符号的选择对文本最为重要,文本是最常见的字节数据,因为字符编码是无符号的。许多字符编码的最高位都被置位。用符号扩展的 lb 加载其中一个会产生负数,此时与普通的正字符编码进行比较就会失败。对于文本,请使用 lbu,即无符号加载字节;它用 0 填充高位。对于有符号数据,例如可正可负的小偏移量,请使用 lb。
RISC-V 手册将 lb 和 lbu 定义为半字加载的 8 位版本,其有效地址同样是寄存器 rs1 加上符号扩展的 12 位偏移量。内存按字节寻址,因此一个地址标识一个字节。
字节之间相隔一个地址,因此循环通过将地址加 1 来遍历字节数组。典型的循环读取一个字节,检查它是否为零(文本结束的标记),对其执行操作,然后将地址加 1 向前推进。
示例
.data val: .byte -5 .text la t0, val lb t1, 0(t0) # t1 = -5 (sign-extended)
