Memory MIPS双字边界和堆栈指针
在MIPS中,为了存储双精度(8字节),堆栈指针Memory MIPS双字边界和堆栈指针,memory,stack,mips,mars-simulator,Memory,Stack,Mips,Mars Simulator,在MIPS中,为了存储双精度(8字节),堆栈指针$sp递减4: addi $sp, $sp, -4 s.d $f10, 0($sp) 这对我来说没有意义,因为内存中占用了8个字节,但堆栈指针移动时就好像使用了单个字边界一样。要存储两个double,堆栈指针似乎应该减少12,而不是预期的16: addi $sp, $sp, -12 s.d $f10, 0($sp) s.d $f12, 8($sp) 为什么会发生这种行为?如果递归调用子例程(第一次对齐,第二次
$sp
递减4:
addi $sp, $sp, -4
s.d $f10, 0($sp)
这对我来说没有意义,因为内存中占用了8个字节,但堆栈指针移动时就好像使用了单个字边界一样。要存储两个double,堆栈指针似乎应该减少12,而不是预期的16:
addi $sp, $sp, -12
s.d $f10, 0($sp)
s.d $f12, 8($sp)
为什么会发生这种行为?如果递归调用子例程(第一次对齐,第二次不对齐),则会导致问题
编辑:我正在用MARS 4.5运行此代码<代码>s.d$f10,8($sp)翻译成
lui $1,0
addu $1,$1,$29
sdc1 $f10,8($1)
堆栈指针在此期间不移动。单步遍历它看起来像是
sdc1
将$f10
和$f11
同时放入堆栈中 检查$sp是否恰好被设置为不是8的倍数的值。如果是这样,请尝试以下操作:andi$sp,$sp,0xfffffff8
。这将使$sp下降到8的下一个倍数。但是,您需要小心,以便能够正确地将$sp返回到其原始值。是什么/谁生成了此代码(即,是什么/谁决定减少堆栈指针的多少)?在火星上,s.d
是一种伪指令。也许在完整程序的上下文中查看伪指令扩展将有助于回答您的问题。@Zack我已经更新了原始帖子。我还认为堆栈指针应该减少8,而不是4。是什么让你认为8不正确?@Zack唯一的原因是MARS在0x0040000c处抛出一个错误运行时异常:地址未在双字边界0x7fffeff4
(对于addi$sp,$sp,-8
)我使用add$sp,$sp,-4
和add$sp,$sp,4
,这基本上是等效的。火星错误背后的原因是我更感兴趣的。MIPS要求数据“对齐”。这意味着字数据的地址必须是4的倍数,双字数据的地址必须是8的倍数。假设$sp恰好被初始化为8的倍数,然后推一个整数,然后推一个双字浮点。第二次推送将导致运行时错误,因为$sp不再是8的倍数。上面的andi
“向下舍入”;它不减法。