Search code examples
assemblymipscalling-convention

Who is responsible for saving calle-saved registers in MIPS?


When a subroutine is called in MIPS, since the calle-saved registers($s0-$s7) are preserved across function/subroutine calls, they are saved in the subroutine's stack frame if they're going to be modified. Who is responsible for saving them? Am I the assembly programmer responsible for saving these calle-saved registers by writing instructions to store them onto the stack? Or does the assembler somehow manage the saving of calle-saved registers automatically when calling a subroutine for me so they're preserved across calls? I'm just learning MIPS calling conventions so this is entirely new to me.


Solution

  • Your function doesn't literally have to save / restore them, you just have to make sure they still have their original value when your function returns. The easiest way to do this is to not touch those registers at all.

    Caller vs. callee saved registers is confusing terminology, and incorrectly implies that all registers must be saved somewhere every time there's a function call.

    Much better terminology: call-preserved vs. call-clobbered. In both cases you're looking at the registers from the same perspective, as well as not implying that anyone's actually wasting instructions doing any saving. Just let registers be clobbered if you don't need the value in them after a jal.

    You can use call-clobbered registers like $t0..$t9 for whatever you want, and you can return with them holding whatever garbage is left after your code.

    If you make a function call inside a loop, you'll probably want to save a couple of the call-preserved registers ($s0..$s7) and use one for your loop counter. Then restore it at the end of your function. You don't want to store/reload it yourself inside the loop; that would be a big waste if the function you call doesn't touch the register.