【发布时间】:2018-11-21 05:17:15
【问题描述】:
我是 riscv 的新手,我对 la 和 lw 感到困惑。
我知道la 代表加载地址,lw 代表加载字。如果VAL的地址是0x100,VAL的数据值是0x11应该x3存储0x100和x4 存储 0x11?
la x7, VAL
sw x3, 0(x7)
lw x4, VAL
bne x4, x3
【问题讨论】:
标签: riscv
我是 riscv 的新手,我对 la 和 lw 感到困惑。
我知道la 代表加载地址,lw 代表加载字。如果VAL的地址是0x100,VAL的数据值是0x11应该x3存储0x100和x4 存储 0x11?
la x7, VAL
sw x3, 0(x7)
lw x4, VAL
bne x4, x3
【问题讨论】:
标签: riscv
la t0, SYMBOL 是一个汇编伪指令,它将SYMBOL 的地址放入t0。根据寻址模式,它会扩展为类似
lui t0, SYMBOL[31:12]
addi t0, t0, SYMBOL[11:0]
其中SYMBOL[31:12] 是SYMBOL 的高位,SYMBOL[11:0] 是SYMBOL 的低位——这些不是有效的汇编语法,并且有一些技巧可以使用符号扩展来获得这个完全正确。
lw t0, SYMBOL 是一个汇编伪指令,它将地址SYMBOL 的内存值放入t0。根据寻址模式,它会扩展为类似
lui t0, SYMBOL[31:12]
lw t0, SYMBOL[11:0](t0)
具体区别在于lw 执行从内存加载,而la 只是生成一个地址。顺序
la t0, SYMBOL
lw t0, 0(0)
在功能上等同于
lw t0, SYMBOL
但需要额外的指令,特别是
lui t0, SYMBOL[31:12]
addi t0, t0, SYMBOL[11:0]
lw t0, 0(t0)
对
lui t0, SYMBOL[31:12]
lw t0, SYMBOL[11:0](t0)
这应该都是RISC-V Assembly Programmer's Manual 中的文档,但这始终是一项正在进行的工作。如果您发现缺少这些,请随时提交补丁或打开问题。
【讨论】:
la 计算一个指针大小的有效地址,但不执行任何内存访问。有效地址本身就是加载到 x7 中的内容。
(另请注意,la 是一条伪指令,可以扩展为两条指令,具体取决于VAL — 尽管如此,该序列计算一个有效地址,这就是它的结果(不执行内存访问)。 )
lw 也计算一个有效地址;但是,它在字大小的内存访问中使用有效地址,并且该内存访问的结果是加载到 x4 中的值。
lb 的作用与lw 相同,只是内存访问是字节大小的。
就您的代码序列而言,x3 中的值(无法从您的代码 sn-p 确定)将存储到内存中 0x100-0x103 的位置(这是一个字大小的存储) .
lw 将重新加载由sw 写入的值。 (请注意,这种情况下的lw 也可以根据VAL 扩展为多条指令,而sw 是一条指令,与VAL 无关。)
bne(虽然缺少目标标签)不会分支。
【讨论】:
la 指令是伪指令,它获取符号的地址。在规范中,它的意思是:
来自:规范第 1 卷,非特权规范 v. 20191213 (https://riscv.org/technical/specifications/)
la会根据符号不同:
当la中的符号为non-PIC(non Position Independent Code)时,la将解析为auipc和addi。
当符号为PIC(Position Independent Code)时,la将解析为auipc和l{w|d}。符号将扩展为 GOT[symbol],GOT 表示:全局偏移表。 RV32I用lw,RV64I用ld。
lw 指令将一个 32 位值从内存加载到 rd 中。
所以,这不仅仅是一个简单的“地址”与“价值”问题,还取决于平台和符号。因为 la 会在不同的情况下作为不同的指令来解决。
【讨论】: