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

标签 assembly riscv riscv32

我想将 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/

相关文章:

c++ - 德州仪器数字信号处理器 : interfacing C++ and assembly

riscv - GPL 的 RISC-V 实现?

QEMU riscv32-softmmu,softmmu是什么意思?

assembly - Assembly-RiscV 中的 "not"是什么意思?

assembly - 在 MIPS 中实现 toUpper 函数

c - 不正确的寄存器 0x​​104567910 与 '%rbx' 后缀一起使用

performance - 英特尔 Broadwell 处理器出现明显的 FMA 性能异常

linux - riscv/gcc/ld - "Undefined reference to printf"使用自己的脚本链接

compression - 如何禁止riscv压缩代码?