using multiple mips arguments >4

空扰寡人 提交于 2019-12-24 09:25:10

问题


Im trying to program a function to use extra arguments besides 4 (since my version of mips only supports $a0-$a3) by pushing them on the stack, but my code is incorrect. Here is my code in main (snippet):

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

which sets a temporary value of 40, gives space on the stack, and saves it. My function is then called. As a test to see if this worked, inside the function when i move these temp arguments $a0-$a3 to their saved register counterparts, I have this code:

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

li $v0, 1
syscall

...but it only prints out a 0 and not 40, so im doing something incorrect. Any help would be greatly appreciated (and upvoted)


回答1:


In the most common 32 bit MIPS calling convention, space is reserved on the stack for $a0,$a1,$a2 and $a3, so the called function should expect to find the 5th argument at 16($sp).

The easiest way to figure these things out is to write an empty version of your function in C, and dissassemble the .o file to figure out how the arguments are passed by the compiler.




回答2:


That code is absolutely correct, so the problem lies elsewhere. My best guess is that the stack pointer hasn't been managed correctly up to that point in your code or in printf you have an error before popping off the stack. Why not use the debugger to see what's happening? If you can, post a runnable program with all irrelevant code stripped out that demonstrates the problem. Here's a working MIPS program that does what you're trying to do and uses the same instructions.




回答3:


There's two issues you are dealing with, from looking at the full code you linked above.

1) You're stack isn't being setup properly to use arguments (especially more than four) for the standard MIPS o32 calling conventions. The other answers do a good job of pointing you to help on this.

2) The 'printf' you are using doesn't use standard calling convention whatsoever. If you see the comments:

## 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

Nothing is expected to be passed on the stack. (Remember $s0-6 aren't stack-related). You can provide to this function $a0-> format string, and 3 arguments (in $a1, $a2, and $a3). Note these comments suggests says it destroys $s0-$s6, though from the incomplete code, I can say how much is restored without tracing through it. In short, this printf you found, might be handy, but it does not use stack conventions you should be learning and it is pretty limited. Assuming you have permission to use it, see about getting permission to modify and just rewrite the interface to something sane. Keep in mind having to call the function multiple times if you need to print out more than 3 variables at a time isn't a big deal (if it is, just write a wrapper).



来源:https://stackoverflow.com/questions/10214334/using-multiple-mips-arguments-4

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!