我想将 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)'
我做错了什么以及从直接地址加载单词的更少指令方面的好方法是什么?
最佳答案
0xff8 的十进制数是 4088。该值超出了 lw
(以及所有其他 I-Type 指令)的 12 位带符号立即数的范围。
您可以尝试使用 -8(t0) 之类的语法,虽然这会转换为带有 ff8
立即字段的 lw
机器代码,但它会得到由于符号扩展,地址错误(0x200aff8)。
但是,您的 li
解决方案更易于使用。如果仔细观察 2 指令扩展,您会发现 lui
使用 200c
来减轻 I 上 12 位立即数发生的符号扩展-键入指令。
另外,请注意,您的 li
伪指令方法可能会直接与 lw
一起使用(取决于汇编器):
lw t0, 0x200bff8
但是,如果这是在紧密循环中,则它代表 2 条指令,而 li
形式可用于在循环外部将地址创建到寄存器中,然后在循环内部仅使用简单的需要lw
。
为了实现两者的最佳效果,优化编译器将仅在循环外部放置一个 lui
(而不是 lui/addi 对),然后使用 lw
的单指令形式> 剩余的偏移量。
关于assembly - 如何从 risc-v 汇编中的立即 32 位地址加载一个字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68107583/