问题描述
我想从 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
的一种指令形式和其余的偏移量.