Reputation: 675
I absolutely cannot understand MIPS' stack. Space on the stack is allocated by subtracting the $sp register, the stack grows on the direction of the program, when it grows too much it overflows by overwriting (or at least trying to) the program. Once the function is executed, I must remove the stack by adding the same value I've subtracted first. This is all fine to me. I was told, though, that when I'm saving arguments I must allocate four spaces, corresponding to the four first arguments ($a0-$a3), and never use them (as stated here). Why? Also, when I'm building the stack, I must save extra arguments. Should I save the "not extra" arguments too? e.g. the assembly of this C program:
void f (int x, int y, int z) {
int array[5], a, b;
if (x >= y && x != z)
g(x+1, y+2, z+3, 4, 5);
else
h(x-1, y-2, z-3, 4, 5, 6, 7);
while (z != 0)
x++
}
Should I save $a0-$a3 on their respective stack positions? Should I save them in $s0-$s3? If I didn't have the while part, should I not save them?
Upvotes: 3
Views: 476
Reputation: 1782
Here are links from popular answer on the close thread:
Taken from: Frame Pointer Explanation
Upvotes: 1
Reputation: 18503
It is just a convention that the arguments are passed this way. If you write a program and one of your functions is calling another function also written by you you may also decide to pass all arguments on the stack (instead of $a0-$a3) or do anything different...
However when you call a function not written by you (for example a function generated by a C compiler) or your function is called by such a function you have to assume that the function not written by you behaves like it is described here.
that when I'm saving arguments I must allocate four spaces, corresponding to the four first arguments ($a0-$a3) and never use them (as stated here). Why?
Early MIPS processors were designed for high-end computers so the main objective behind these conventions was speed and not usability.
I was just thinking about this "strange" convention: There are many cases when this convention will generate the fastest possible code. So this is the reason.
Should I save the "not extra" arguments too?
You may do this; however the function you call will ignore the data stored there.
When writing an own compiler (I already did) it should be much easier when you DO store the "not-extra arguments" on the stack - so this could be a reason to do it.
Upvotes: 3
Reputation: 6266
MIPS calling conventions from Wikipedia
The most commonly used1 calling convention for 32 bit MIPS is the O32[2] ABI which passes the first four arguments to a function in the registers $a0-$a3; subsequent arguments are passed on the stack. Space on the stack is reserved for $a0-$a3 in case the callee needs to save its arguments, but the registers are not stored there by the caller. The return value is stored in register $v0; a second return value may be stored in $v1.
You can modify the $t0
,...$t9
registers without saving them on the stack, but they can be modified by any functions your code calls. If you need to use $s0
,...,$s7
, you must save them on the stack and restore them before returning.
Upvotes: 3