我知道每当我在MIPS中有一个具有四个以上参数的函数时,我应该利用堆栈。但是在保存第sw $t0, 4($sp)
的第五个参数并执行jal sad
之后的下面的代码中,然后在sad
函数的开头我再次调整堆栈指针以保存{{1调用者使用的寄存器。我在这里做错了吗?
$sx
答案 0 :(得分:5)
这是由gcc完成的。有关更多信息,您(可以)应阅读 Mips ABI。有些事情可能有所不同。
http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf
按照惯例,第五个参数应该放在堆栈的第五个字上。
所以你应该
sad:
sub $sp,$sp,24 #24 byte stack frame
... some code ...
#Convention indicates to store $a0..$a3 in A..D (see below)
sw $a0,0(sp)
sw $a1,4(sp)
sw $a2,8(sp)
sw $a3,12(sp)
#Get the 5th argument
lw $t0,40($sp) #40 : 24 + 16
要将第五个参数存储在堆栈中,您应该知道:
如果vbsme要调用另一个函数,那么应该保存堆栈的底部4个单词,以便被调用者在那里存储参数值。如果传递的参数超过4个,则应为每个参数保存一个附加单词。
vbsme's stack frame bottom part (Argument building area)
| ... |
---------------
| 5th arg | <---- sw $t5,16($sp)
---------------
| D |
---------------
| C |
---------------
| B |
---------------
| A |
--------------- <--sp (of vbsme stack frame)
此外,$ ra寄存器应保存在堆栈顶部,因为它的寄存器为31。
vbsme:
subu $sp, $sp, 20+N # 20: space for 5 arguments,
#N space for other stuff (ra,$tx, etc)
#Set arguments (assumes 5th parameter value is in register $t5)
subi $a3, $s0, 1 # 4th parameter: i-1
sw $t5,16($sp) #
...
.end
Why is it that you do:
lw $t0,40($sp)
to get the 5th argument, why did you add 24 to 16? when you do
sub $sp,$sp,24
don't you already move
the sp 24 place?
是的,$ sp + 24指向来电者堆栈的基础。然而,那不是我放置第五个参数的地方。第五个参数放在调用者堆栈的第五个单词上,这就是我添加16的原因。