试图理解mips中的.data以及如何调用函数

时间:2015-10-06 01:35:11

标签: assembly mips

让我说如果我有

.data
prompt1 .asciiz " string1 "
prompt2 .asciiz " String2 "

.text
main: 
     addi $v0, $0, 4
     lui  $a0, 0x1000  #this will give me prompt1

那么我如何得到提示2及其背后的工作原理呢?如果有人可以使用lui向我解释它以及使用la的优势或劣势,那就最好。

2 个答案:

答案 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并将地址保留在寄存器中,只要您需要/可以。所以,你去了,优点和缺点。