如何从 risc-v 汇编中的立即 32 位地址加载一个字?

问题描述

我想从 0x0200bff8 地址加载一个字到 t1 寄存器。 我尝试了以下方法

 lui t0,0x0200b; // Write Upper 20 bits into t0
 lw t1,0xff8(t0);  //fetch a word from address in t0 offsetted by 0xff8 (12 bits)

我认为它在语法上是正确的,但我看到了这个错误

错误:非法操作数`lw t1,0xff8(t0)'

我做错了什么,从立即地址加载一个字的指令较少,有什么好方法

解决方法

我刚刚找到了一个可以完成工作的伪指令 li t0,0x200bff8;

,

0xff8 是十进制的 4088。该值超出了 lw(以及所有其他 I-Type 指令)的 12 位有符号立即数范围。

您可以尝试使用 -8(t0) 之类的语法,虽然这会转换为 lw 的机器码,立即数字段为 ff8,但它会得到错误的地址 (0x200aff8),因为符号扩展。

但是,您的 li 解决方案更易于使用。如果您仔细查看 2 指令扩展,您会发现 lui 使用 200c 来减轻发生在 I-Type 指令上的 12 位立即数的符号扩展。>

另外,请注意您的 li 伪指令方法可能会直接与 lw 一起使用(取决于汇编程序):

lw t0,0x200bff8

然而,如果这是在一个紧密的循环中,它代表 2 条指令,而 li 形式可用于将地址创建到循环外的寄存器中,然后在旁边只有一个简单的 {{1 }} 是必需的。

为了两全其美,优化编译器只会在循环外放置一个 lw(而不是 lui/addi 对),然后使用 lui 的一种指令形式和其余的偏移量.