Use of the stack The purpose of this question is to evaluate your understanding
ID: 3562980 • Letter: U
Question
Use of the stack The purpose of this question is to evaluate your understanding of stack operations in MIPS Consider the following lines of code, representing MIPS function myFunc For this question, we do not are about the functionality of myFunc and therefore, we do not know why myrunc does what it does Our goal is to make sure myFunc follows the conventions of MIPS procedure calls Add as many lines of code you need to complete this function including instruction(s) that allow the function to return to its caller Do not put unnecessary data on the stack There might be more than one correct answer Use the provided callouts to insert your instructions Some callouts may be left empty, if you think no instructions should be inserted in that space move $s0, $a0 move $tO, $a1 move $t1, $a2 jal otherFunc add $s1, $s0, $t0 move $v0, $s1Explanation / Answer
Each subroutine may have a set of variables local to that subroutine. These variables can be conveniently stored on a stack in a stack frame. Some calling conventions pass arguments on the stack as well.
Using subroutines also means you have to keep track of the caller, that is the return address. Some architectures have a dedicated stack for this purpose, while others implicitly use the "normal" stack. MIPS by default only uses a register, but in non-leaf functions (ie. functions that call other functions) that return address is overwritten. Hence you have to save the original value, typically on the stack among your local variables. The calling conventions may also declare that some register values must be preserved across function calls, you can similarly save and restore them using the stack.
Suppose you have this C fragment:
MIPS assembly may then look like:
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:
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.
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.
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.