CPR E 281x/282x - Lab 9b
C
to MIPS Assembly
Language
1. Objectives
In this lab you will convert
a segment of C code to MIPS assembly language.
1.1
Reference
Files for Lab
2. Prelab
Before you come to lab it
will be useful to become familiar with the different MIPS assembly
instructions. You will find information
in Chapter 2 of your text and Appendix A: “Computer
Organization and Design the Hardware/Software Interface” 3rd
Edition by Patterson and Hennessy (Appendix A available online here).
3. System Calls in Spim
SPIM provides a
small set of operating-system-like services through the system call (syscall)
instruction. To request a service, a program loads the system call code into
register $v0 and the arguments into registers $a0.
System calls that return values put their result in register $v0
(or $f0 for floating point results). For example, to
print ``the answer = 5'', use the commands:
.ent main
main:
li $v0,
4 # system call code for print_str
la $a0,
str # address of string to print
syscall # print the string
li $v0,
1 # system call code for print_int
li $a0,
5 # integer to print
syscall # print 5
itself:
j
itself
.data
str: .asciiz " The answer =
"
.end
4. Grade Averaging Program
The following is a segment
of C code to compute average of your homework scores and the total. We are
assuming that your grades are as defined in the array. If you do not like them,
you can rewrite the program again with your own grades.
int sum(int hw[], int numHw)
{
int sumHw =
0;
for
(int i = 0; i < numHw; i++)
{
sumHw
= sumHw + hw[i];
}
return (sumHw);
}
void main()
{
int
total, ave;
int
hw[10 ] = {74, 80, 80, 94, 85, 79, 65, 87, 68, 88};
total
= sum(hw, 10);
ave = total / 10; // integer portion of
average
printf
("%d %d", ave, total);
}
Convert this segment of C
code into MIPS assembly. Begin with the
template code lab9b_p4.asm. Open the file with Notepad to edit. In the main
routine, the parameters for the sum function (int hw[], int numHw ) have
been set up for you in registers $4 and $5.
Also a template for the sum
function is given. Note that the
function prologue and epilogue have been written for you. You will cover prologues and epilogues in
detail in class, for now it is sufficient to note that the prologue must allocate
space on the stack, and save register values there, while the epilogue must
restore the register values, and de-allocate space on the stack (in practice,
only register values that will be modified by the function are saved, for
simplicity the template saves all non-volatile registers).
More information on
procedure calls is available in in Appendix A.6 of Hennessy and Patterson and at this website.
Note: The .data section at the end of the code
can be used to specify constants for your assembly code to use. In the template, the .data section is used to
hold the array
int hw[10].
This section can also be used to store strings for printing (see system call example above).
When you are finished
coding, run PCSpim and open your lab9b_p4.asm. You should be able to load the
assembly if syntax is correct. Use PCSpim
to check if your program is functioning as expected.
Ask your TA to check and
initial.
5. Towers of
Using SPIM, write and test a recursive program for
solving the classic mathematical recreation, the Towers of Hanoi puzzle. (This
will require the use of stack frames to support recursion.) The puzzle consists
of three pegs (1, 2, and 3) and n disks (the number n can vary;
typical values might be in the range from 1 to 8). Disk 1 is smaller than disk
2, which is in turn smaller than disk 3, and so forth, with disk n being
the largest. Initially, all the disks are on peg 1, starting with disk n on
the bottom, disk n – 1 on top of that, and so forth, up to disk 1 on the
top. The goal is to move all the disks to peg 2. You may only move one disk at
a time, that is, the top disk from any of the three pegs onto the top of either
of the other two pegs. Moreover, there is a constraint: You must not place a
larger disk on top of a smaller disk. The C program below can be used to help
write your assembly language program.
/* move n smallest disks
from start to finish using extra */
void
if(n
!= 0){
print_string(“Move
disk”);
print_int(n);
print_string(“from
peg”);
print_int(start);
print_string(“to
peg”);
print_int(finish);
print_string(“.\n”);
}
}
main()
{
int
n;
print_string(“Enter
number of disks>“);
n
= read_int();
return
0;
}
The following
code shows how to read an input from terminal:
.ent main
main:
li $v0, 4 # Here, we load the value for our macro print_str
la $a0, str1 # We pass the argument with the string
syscall # Print the string
li $v0, 5 # value for macro read_int
syscall # Get integer
move $t1, $v0 # $t1 = $v0
.data
str1: .asciiz " Please enter
a number >= 1 : "
Ask your TA to check and
initial.