sections in this module | City
College of San Francisco - CS270 Computer Architecture Module: MIPS-II (Decisions) |
module list |
Loops
There is nothing special about translating loops for MIPS code. It proceeds the same as it did for the Simple Machine, but it is again much easier to generate MIPS code than it is to generate Simple Machine code.
First, we will do a couple of simple loops. Then we will get right into a mid-level example to give us some practice. Before we do that, however, we will change how we use MARS:
Using the trap handler
Until now we have been using MARS to assemble raw programs with no support. This means we have defined the overall starting point for our program __start and we have had no support if we encountered an error.
Beginning now, we will use the trap handler. The trap handler (/usr/local/lib/exceptions.s on our linux machines) defines __start and calls a function named main(), which we will now define as the beginning of our code. At the end of our function we should return to the trap handler (return from main() ). This is done by simply jumping to the address stored in the register $ra (return address)
Simple:
A simple loop for practice
First, let's start with a simple while loop
In our first pass, we will translate the loop "stupidly" - i.e., just as it appears. First, let's transform it to our ugly version that uses gotos
Now we will write the code, interspersing the original source code. We will assume that A and N are global variables.
This loop is whileloop1.s in the online/mipsII directory.
You probably noticed that there was some redundancy here. This loop requires us to calculate the address of A[i] several times each iteration. So let's add a couple of additional variables to it to see if we can optimize it. Here is the modified original code:
We introduced integer pointers when we were covering the Simple Machine. Let's take a moment and clarify something about C syntax before we continue.
If iptr is a pointer that points to an integer, and we want it to point to an integer i (that is, iptr holds the address of i), the declaration of iptr is
int *iptr, i;
this means that iptr is a pointer to an int. (Note that the * only applies to iptr, not to i. i is just an int.) The * in a declaration means 'is a pointer to'.
You initialize iptr to point to an integer using the addressof operator (&) like this
iptr = &i;
Now the confusing part. To use the address in iptr and get the integer it points to you use * in an assignment statement like this
int j = *iptr;
In an assignment statement, * means dereference, or go through the pointer and get what it points to.
Let's go ahead now and change this to our ugly version of code:
And, finally, to our MIPS code:
This loop is whileloop2.s in the online/mipsII directory.
The last optimization that could be done to this is noticing that it is not necessary to recalculate &A[i] each iteration. Each iteration just adds 4 to the pointer. Can you modify this program for that optimization?
Now, let's proceed with a more complicated loop example:
A moderately-complex loop
Here is the code we want to translate:
Some of you may recognize this as a bubblesort routine, where A is an integer array of N elements. You may immediately realize that this is going to be a bit complicated. Again, take it one step at a time.
Start with the standard translation to gotos
Ugly, isn't it? (Believe me, it's more ugly without the
indentation and blank lines!)
The pre- and post- transformed C code are in the files bubblesort.c and bubblesort1.c in the online/mipsII directory on hills.
Last step, let's translate this to MIPS. Before we do that, let's decide how to use our registers:
First, the data region. We will initialize a simple integer array of 10 elements:
.dataNow the .text region with the initialization of our variables
(above)
Prev | This page was made entirely
with free software on linux: Kompozer, the Mozilla Project and Openoffice.org |
Next |