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

 

Lab Evaluation Form

 

lab9b_p4.asm

 

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 Hanoi Program

 

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 hanoi(int n, int start, int finish, int extra){

if(n != 0){

hanoi(n-1, start, extra, finish);

print_string(“Move disk”);

print_int(n);

print_string(“from peg”);

print_int(start);

print_string(“to peg”);

print_int(finish);

print_string(“.\n”);

hanoi(n-1, extra, finish, start);

}

}

 

main()

{

int n;

print_string(“Enter number of disks>“);

n = read_int();

hanoi(n, 1, 2, 3);

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.