Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

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

image text in transcribed

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

blur-text-image

Get Instant Access with AI-Powered Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Students also viewed these Databases questions