让我说如果我有
.data
prompt1 .asciiz " string1 "
prompt2 .asciiz " String2 "
.text
main:
addi $v0, $0, 4
lui $a0, 0x1000 #this will give me prompt1
那么我如何得到提示2及其背后的工作原理呢?如果有人可以使用lui向我解释它以及使用la的优势或劣势,那就最好。
答案 0 :(得分:1)
我不熟悉MIPS,但这些是标签,而不是功能。您应该能够使用la
指令(加载地址)来引用他们的位置,例如la $a0, .prompt1
或.prompt2
,如果这是您所追求的。
lui
是Load Upper Immediate:它将立即的16位值加载到寄存器的高16位。因此lui %a0 0x1000
位于C register x = 0x1000 << 16 /* 0x10000000 */
中。那为什么会存在呢?为什么不只是这样的“立即加载”指令:li %a0 0x10000000
?那么,MIPS有32位指令,前16个指令用于编码指令名和要使用的寄存器,因此我们只能使用16位立即数值。
要将32位值输入寄存器,例如(再次在C中):register x = 0x10002000
我们需要两条指令,首先加载高位(lui %a0 0x1000
)然后加载低位( addi %a0, 0x2000). So if .prompt1 is at address 0x1000000 and you can get there using
lui`然后转到.prompt2,您可能需要添加一个16位的立即值。
答案 1 :(得分:1)
要将变量的地址放入寄存器,通常在MIPS汇编中写入:
la $v0, prompt1
然后将其内容加载到您要执行的寄存器中(假设您对其第一个字节感兴趣):
lb $v1, 0($v0)
并存储(到第一个字节):
sb $v1, 0($v0)
现在,la
中的la $v0, prompt1
是宏指令,这意味着CPU中没有这样的实际指令。它通常会扩展为CPU中存在的以下两条指令:
lui $v0, %hi(prompt1)
addu $v0, %lo(prompt1)
第一个加载$ v0的第31到16位,其中第1位用于提示1的地址。第二个加载其余的位,15到0。
所以,如果你仔细观察上面的la后跟lb,你会发现它们背后有三条实际指令:
lui $v0, %hi(prompt1)
addu $v0, %lo(prompt1)
lb $v1, 0($v0)
但你可以做得更好:
lui $v0, %hi(prompt1)
lb $v1, %lo(prompt1)($v0)
当然,同样可以通过存储来完成。
因此,如果您只需要访问一次变量,就可以使用双指令序列(两个中的第一个为lui
)来读取或写入它。如果您需要某些内容的实际地址(例如,如果您想将其传递给printf
),那么您需要使用la
。如果您需要两者,请使用la
并将地址保留在寄存器中,只要您需要/可以。所以,你去了,优点和缺点。