20-12-2016, 03:41 AM
|
Posts: 13
Threads: 6
Joined: Mar 2016
|
(17-12-2016, 11:11 PM)shygoo Wrote: Register values that are needed later are normally saved to the calling function's stack frame before jumping
See this reference for standard register usage: http://n64dev.org/registers.html
And some more in-depth reading material: https://acm.sjtu.edu.cn/w/images/d/db/MIPSCallingConventionsSummary.pdf
Example C code:
void main(){
u32 stack_variable = 5;
PrintInt(stack_variable);
PrintInt(stack_variable + 1);
}
MIPS equivalent:
main:
addiu sp, sp, -8 ; allocate a new stack frame with 8 available bytes
sw ra, 0x00(sp) ; save return address to the stack
ori a0, r0, 5 ; load 5 into the arg0 register
sw a0, 0x04(sp) ; save to the stack frame (set stack_variable to 5)
jal PrintInt ; call PrintInt(5)
nop
lw a0, 0x04(sp) ; load stack_variable (a0 may have had garbage in it from the previous PrintInt call)
addiu a0, a0, 1
jal PrintInt
nop
lw ra, 0x00(sp) ; load return address
jr ra ; return
addiu sp, sp, 8 ; deallocate stack frame
Anything is possible while handwriting asm though. If you absolutely need to, you may opt for hacky non-standard callee preservation:
a_haram_function:
addiu sp, sp, -16
sw t0, 0x00(sp)
sw t1, 0x04(sp)
sw ra, 0x08(sp)
nop
nop ; do whatever here
nop
lw t0, 0x00(sp) ; restore calling function's registers before returning
lw t1, 0x04(sp)
lw ra, 0x08(sp)
jr ra
addiu sp, sp, 16
Thanks for these details. I think I'm a bit confused still. In your example, you have "addiu sp,sp,-16", and then sw for t0,t1, and ra. However, The function I am in has all the registers filled with values (by the time I need to jump) - does this mean I need to sw all of the registers in order to call them back later?
Do you think the following Would work in principle?
beginning of function 1
addiu sp, sp, $0028 <-- this is actually the value of the beginning of the real function
... code
... code using regs
... code
insert first part of your code here:
addiu sp, sp, -16
sw t0, 0x00(sp)
sw t1, 0x04(sp)
sw ra, 0x08(sp)
jump to function 2 (which has completely different reg values)
...code
...code
...code
...code
insert next part of your code here:
lw t0, 0x00(sp)
lw t1, 0x04(sp)
lw ra, 0x08(sp)
jr ra
addiu sp, sp, 16
Is the location of your code correct in the above example?
|