gabrieljcs
gabrieljcs

Reputation: 675

MIPS' stack causes my brain to overflow

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

Answers (3)

Ruslan Gerasimov
Ruslan Gerasimov

Reputation: 1782

Here are links from popular answer on the close thread:

Taken from: Frame Pointer Explanation

Upvotes: 1

Martin Rosenau
Martin Rosenau

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

markgz
markgz

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

Related Questions