Use of Frame Pointer MIPS
Solution 1
I found @markgz's comments to be interesting. His link to Wikipedia includes the quote:
The frame pointer ($30) is optional and in practice rarely used except when the stack allocation in a function is determined at runtime, for example, by calling alloca().
I always kinda thoght that $fp
seemed superfluous, but I always used it anyway because that's how I was taught to do it.
Anyway, if you are still interested, here is how I used the frame pointer:
#save $ra $s0, $a0 on stack
addi $sp $sp -4
sw $fp 0($sp)
move $fp $sp
addi $sp $sp -12
sw $ra -4($fp)
sw $a0 -8($fp)
sw $s0 -12($fp)
...
#restore and shrink stack
lw $s0 -12($fp)
lw $ra -4($fp)
lw $fp 0($fp)
addi $sp $sp 16
jr $ra
So each time the stack is expanded, I use the stack-pointer to save the old value of the frame pointer, and then I restore the old value of the frame pointer when shrinking the stack.
Mostly I just copy and paste this code every time I write a new function.
Solution 2
You should never convert MIPS code to use the Frame Pointer instead of the Stack Pointer, because that would violate MIPS Calling Convention, and your code would cease to work with other people's code.
The Frame Pointer is not typically used in hand coded MIPS assembler, because the stack pointer does not change value during the execution of a function. Indeed, your own code is correctly coded so that the stack pointer never changes value.
Justin Homes
Updated on June 04, 2022Comments
-
Justin Homes almost 2 years
i need to convert my code from stack pointer to only use frame pointer, how can i do so? i am very new to MIPS.
i have this recursion C code and its MIPS code below. i am using stack pointer , how can i change it to use frame pointer?
here is my C Code
int fact(int n) { if(n!=1) return n*factorial(n-1); } int comb (int n, int k) { return fact (n) / fact (k) / fact (n - k); }
here my MIPS code
comb: sub $sp, $sp, 16 sw $ra , 0($sp) sw $s0, 4($sp) sw $a0, 8($sp) sw $a1, 12($sp) jal fact move $s0, $v0 lw $a0, 12($sp) jal fact div $s0, $s0, $v0 lw $a0, 8($sp) lw $a1, 12($sp) sub $a0, $a0, $a1 jal fact div $s0, $s0, $v0 move $v0, $s0 lw $ra, 0($sp) lw $s0, 4($sp) addi $sp, $sp, 16 jr $ra
-
Justin Homes about 10 yearsdon't we need to store a1 and need to allocate like addi $sp $sp -16 instead of addi $sp $sp -12
-
Konrad Lindenbach about 10 yearsThis was just an example of what you would do if you wanted to store
$ra
,$s0
and$a0
. You could store all 32 registers if you wanted. -
Justin Homes about 10 yearsi get error like this can't expand stack segment by 12 bytes to 1048576 bytes yse -lstack # with # >1048756 when i do addi $sp $sp -4 sw $fp 0($sp) move $fp $sp addi $sp $sp -16 sw $ra -4($fp) sw $a0 -8($fp) sw $s0 -12($fp) sw $a1, -16($sp)
-
Konrad Lindenbach about 10 yearsThat should be
sw $a1, -16($fp)