2013-02-18 223 views
0

我在MIPS手册中阅读: “注意我们使用”add immediate“指令的”无符号“版本,因为我们正在处理一个地址,它是一个无符号的二进制数。不会因为计算的地址跨越内存空间的中点而产生异常。“MIPS:使用堆栈

这是什么意思?特别跨过内存空间的中点。

而且,在下面的代码中,我不明白为什么它从8($ sp)跳到20($ sp)。代码后来从12($ sp)和16($ sp)加载,但是什么时候对这些内存部分做了些什么。我想在JAL JILL中可能,但是没有给出太多的解释。

addiu $sp, $sp, -24 
sw $t1, 0($sp) 
sw $t2, 4($sp) 
sw $t3, 8($sp) 
sw $ra, 20($sp) 
jal JILL 
lw $ra, 20($sp) 
lw $t4, 12($sp) 
lw $t5, 16($sp) 
addiu $sp, $sp, 24 
+0

它不是一个“无符号加法”它是带有“无符号溢出异常”的附加。加法操作本身并不知道这些位的解释。 – 2013-02-19 05:03:07

回答

1

Assumming一个MIPS32架构,其具有32位的地址空间,存储空间的中点。将地址0x80000000的(即2^31)。 在32位有符号(A2-补充)运算中,从0到0x7FFFFFFF的整数保留给正数,0x80000000到0xFFFFFFFF的整数保留给负数。

当您发出已签名的添加时,如果添加的结果“交叉”该中点,则会发生溢出异常。但在你的例子中,你实际上处理的是内存地址,而不是有符号数......因此地址的符号(解释为32位数)是没有意义的,所以你应该使用无符号加法。

关于你提到的第二个问题,你必须寻找到吉尔程序,看看会发生什么......肯定有程序将存储一些信息12($sp)16($sp)

+0

所以,如果我正确地理解了你的意思,那只是为了防止由于补码的加入而可能发生的溢出异常。关于第二个问题,上面的实现和JILL中的堆栈调整之间有什么区别?在代码和概念上会更困难吗? – John 2013-02-18 16:07:18

+0

是的,只是为了防止堆栈位于内存空间中点附近时可能出现的溢出异常。关于你的第二个问题,这一切都取决于用于调用其他过程的调用约定。在你的例子中,调用者为被调用的过程保留堆栈空间以存储结果,然后从调用者返回时程序使用结果并释放使用的堆栈空间。由于某些寄存器需要由调用者保存($ t1,$ t2,$ t3和$ ra),因此您不能轻易将该行为移至JILL过程。 – gusbro 2013-02-18 17:11:15

+0

您是否介意详细说明最后一句话? – John 2013-02-18 18:22:36