Question
C/C++ to Mips main() { x = 2*foo(4*y+4); x = x+(4*y+4); } int foo (int n) { int junk[10] = {0,1,2,3,4,5,6,7,8,9}; int junk2[16]; // Mod
C/C++ to Mips
main() {
x = 2*foo(4*y+4);
x = x+(4*y+4);
}
int foo (int n) {
int junk[10] = {0,1,2,3,4,5,6,7,8,9};
int junk2[16]; // Mod 1 (stored below (i.e.,higher address) junk on stack)
junk[4] += 2 - junk2[7]; // Mod 2
if (n
else return 2*bar(1,2,3,4,5,6+n) + junk[4] + foo(n-1); // Mod 3
}
Modify the following assembly language for this revised program. You may assume that bar is an OS function that has already been written. Of course, you have to use the procedure convention described in class. In cases where the convention was left unspecified, use the convention of the example. Also note that we need to call bar before foo as in the HLL code, since the compiler doesnt know whether bar has side effects such as [unadvisedly] playing with pointers to modify a variable in foo. Make sure to use a different ink color (or boldface font) to make your modifications clear, and label your program to indicate which changes support which mod. DO NOT change the original code, except as needed for these modifiations.
Thank you.
The assembly code I gave
in class (or a slight variation) is below:
# Allocate Registers:
x$s0, y$s1
# Assume optimizing compiler avoids computing 4*y+4 twice
Main: add $t0,$s1,$s1 # $t0 2y
add $t0,$t0,$t0 # $t0 4y
addi $t0,$t0,4 # $t0 4y+4
addi $sp,$sp,-4 # Push $t0
sw $t0,0($sp)
add $a0,$t0,$zero # arg0 4y+4
jal Foo # Call foo
lw $t0,0($sp ) # Pop $t0
addi $sp,$sp,4 #
add $s0,$v0,$v0 # x 2*foo(4*y+4)
add $s0,$t0,$s0 # x x+4*y+4
... # End of Main
Foo: addi $sp,$sp,-48 # Push:
sw $ra,44($sp) # $ra
sw $fp,40($sp) # $fp
addi $fp,$sp,44 # Set $fp to point to frame
add $t1,$zero,$zero # $t1 0
sw $t1,-44($fp) # junk[0] 0
addi $t1,$t1,1 # $t1 1
sw $t1,-40($fp) # junk[1] 1
...
addi $t1,$t1,1 # $t1 9
sw $t1,-8($fp) # junk[9] 9
lw $t1,-28($fp) # $t1 junk[4]
addi $t1,$t1,2 # $t1 junk[4]+2
sw $t1,-28($fp) # junk[4] junk[4]+2
slti $t0,$a0,1 # $t0 1 if n
bne $t0,$zero,RetOne # Return 1 if n
# Call foo(n-1)
addi $sp,$sp,-4 # Push
sw $a0,0($sp) # ... $a0
addi $a0,$a0,-1 # arg0 n-1
jal Foo # Call foo(n-1)
lw $a0,0($sp) # Pop $a0
addi $sp,$sp,4
lw $t1,-28($fp) # $t1 junk[4]
add $v0,$v0,$t1 # $v0 foo(n-1)+junk[4]
j Ret # Return
RetOne: addi $v0,$zero,1 # $v0 1
Ret: lw $fp,40($sp) # pop $fp
lw $ra,44($sp) # pop $ra
addi $sp,$sp,48 # reclaim stack space
jr $ra # return to call
This is the procedure convention
The Conventioin There are three general groups of steps in our convention: caller pre-call, callee, and caller post-cal. Caller Pre-Call 1. Push caller-saved registers onto stack. Of course, only those registers whose values will be needed after the call are saved 2. If there are more than 4 arguments, push the extra arguments onto the stack. 3. Place first four arguments in Sa0,.. .,Sa3. 4. Execute the jal instruction, which implicitly saves the return address in Sra. Callee We assume that the callee needs n bytes for callee-saved registers (including Sra) and variables local to the callee. The callee executes the following steps: 1. Subtract n from Ssp, to make room for the n bytes. 2. Store callee-saved registers to the appropriate part of the frame (see stack diagram). 3. Set Sfp to Ssp +n-4, so that it points to the saved return address 4. Execute callee instructions 5. Place return value/s in Sv0 (and Svl if needed 6. Restore all saved registers (but not local variables) from frame 7. Free stack space by adding n to Ssp 8. Execute jr Sra (only one per function allowed). Caller Post-Call 5. Pop any extra] arguments that were pushed onto the stack. 6. Pop caller-saved registers from stack. 7. Continue executing rest of caller, assuming the callee's return value is in Sv0 (and Sv1) The Conventioin There are three general groups of steps in our convention: caller pre-call, callee, and caller post-cal. Caller Pre-Call 1. Push caller-saved registers onto stack. Of course, only those registers whose values will be needed after the call are saved 2. If there are more than 4 arguments, push the extra arguments onto the stack. 3. Place first four arguments in Sa0,.. .,Sa3. 4. Execute the jal instruction, which implicitly saves the return address in Sra. Callee We assume that the callee needs n bytes for callee-saved registers (including Sra) and variables local to the callee. The callee executes the following steps: 1. Subtract n from Ssp, to make room for the n bytes. 2. Store callee-saved registers to the appropriate part of the frame (see stack diagram). 3. Set Sfp to Ssp +n-4, so that it points to the saved return address 4. Execute callee instructions 5. Place return value/s in Sv0 (and Svl if needed 6. Restore all saved registers (but not local variables) from frame 7. Free stack space by adding n to Ssp 8. Execute jr Sra (only one per function allowed). Caller Post-Call 5. Pop any extra] arguments that were pushed onto the stack. 6. Pop caller-saved registers from stack. 7. Continue executing rest of caller, assuming the callee's return value is in Sv0 (and Sv1)Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started