使用多个mips参数> 4

时间:2012-04-18 17:05:14

标签: mips spim pcspim

我试图编写一个函数来使用4之外的额外参数(因为我的mips版本仅支持$ a0- $ a3)通过在堆栈上推送它们,但我的代码是不正确的。这是我在main(代码段)中的代码:

li $t0,40 #temp value for our 5th arg.

addi $sp, $sp, -4 #decrement stack pointer by 4
sw $t0, 0($sp) #save the value of $t0 on the stack.

jal printf

设置临时值40,在堆栈上给出空间并保存。然后调用我的函数。作为测试是否有效的测试,当我将这些临时参数$ a0- $ a3移动到他们保存的寄存器对应的函数内部时,我有这样的代码:

lw $t0, 0($sp) 
addi $sp, $sp, 4
move $a0,$t0

li $v0, 1
syscall

...但它只打印出0而不是40,所以我做的事情是不正确的。任何帮助将非常感谢(和upvoted)

3 个答案:

答案 0 :(得分:1)

在最常见的32位MIPS calling convention中,空间在$a0,$a1,$a2$a3的堆栈上保留,因此被调用函数应该期望在{{1}处找到第5个参数}}

解决这些问题的最简单方法是在C中编写函数的空版本,并对16($sp)文件进行反汇编以确定编译器如何传递参数。

答案 1 :(得分:0)

该代码绝对正确,因此问题出在其他地方。我最好的猜测是,在代码中的那一点上没有正确管理堆栈指针,或者在弹出堆栈之前printf你有错误。为什么不使用调试器来查看发生了什么?如果可以的话,发布一个可运行的程序,其中删除了所有无关代码以证明问题。 Here是一个有效的MIPS程序,可以执行您尝试执行的操作并使用相同的说明。

答案 2 :(得分:0)

通过查看上面链接的完整代码,您正在处理两个问题。

1)对于标准MIPS o32调用约定,您没有正确设置堆栈以使用参数(尤其是4个以上)。其他答案很好地指导你帮助解决这个问题。

2)您使用的'printf'不使用任何标准调用约定。如果你看到评论:

## printf--
## A simple printf-like function. Understands just the basic forms
## of the %s, %d, %c, and %% formats, and can only have 3 embedded
## formats (so that all of the parameters are passed in registers).
## If there are more than 3 embedded formats, all but the first 3 are
## completely ignored (not even printed).
## Register Usage:
## $a0,$s0 - pointer to format string
## $a1,$s1 - format argument 1 (optional)
## $a2,$s2 - format argument 2 (optional)
## $a3,$s3 - format argument 3 (optional)
## $s4 - count of formats processed.
## $s5 - char at $s4.
## $s6 - pointer to printf buffer

预计不会在堆栈上传递任何内容。 (记住$ s0-6与堆栈无关)。你可以提供这个功能$ a0->格式字符串和3个参数($ a1,$ a2和$ a3)。 注意这些评论表明它会破坏$ s0- $ s6,虽然从不完整的代码中,我可以说在没有追踪它的情况下恢复了多少。简而言之,您发现的这个printf可能很方便,但它不使用您应该学习的堆栈约定,而且非常有限。假设您有权使用它,请参阅获取修改权限,并将界面重写为理智。请记住,如果您需要一次打印超过3个变量,则必须多次调用该函数并不是什么大问题(如果是,只需编写一个包装器)。