Lab 10

Cross-compiling C to MIPS

You may complete this assignment with a partner (group size: 1 or 2 only). If you work with a partner on these exercises, make sure that you both understand all aspects of your solutions. Check off will be individual, and is independent of partnerships.

Be very careful to follow these directions exactly. The slightest error can cause a lot of trouble for you in the future.

Exercise 1: Cygwin

Cygwin is a Linux-like environment for Windows, consisting of a DLL (cygwin1.dll, which acts as a Linux API emulator layer providing substantial Linux API functionality) and a collection of tools (which provide Linux look and feel).
  1. Download the following to your desktop:
    - setup.exe
    - cygwin-2006april23.rar
  2. Decompress cygwin-2006april23.rar to the desktop.
  3. Double click on setup.exe and select to "Install from Local Directory"
  4. Leave all options default and install at C:\cygwin.

We will use this software in exercises 2 & 4. If time permits, you may read more about Cygwin here.

Exercise 2: Cross-compilers

Normally one architecture cannot compile code for another. Using GNU tools along with Cygwin, here's a "cross-compiler" which generates code for a different machine architecture other than the one running the compiler. Our cross-compiler is compiling code for the MIPS architecture even though it is running on a Windows PC machine.

1. Download the following:

 - x86.win32

2. Place the downloaded file above into the Cygwin home directory (cd ~). To find out where this is, open up Cygwin and type "cd ~" and then "pwd" to see the path of the current directory displayed. This will correspond to the directory starting after C:/cygwin/...~.../ to location the downloaded file above should be placed in Windows (probably something similar to: C:/cygwin/home/username/). Replace "~" with the home directory in the commands below, but start after C:/cygwin (start with /home/...).

3. In Cygwin, run the following commands:

 tar -xvzf ~/mips-x86.win32-xgcc.gz

This will extract the compressed files.

4. In Cygwin, set the ARCHDIR environment variable to point at the cross-compiler directory:


5. Prepend the PATH environment variable to point at the cross-compiler directory:


This prepends the directory to our system path. Note that we must keep /usr/bin in our PATH so we must prepend the current path (include the previous/current $PATH at the end).

We will test/use this in exercise 4. If you're interested in more information on building your own cross-compiler, look here.

Warning: This cross-compiler is very sensitive and "as is" is not set up to do complex compiling. If you would like to set up advanced features (such as including libraries, etc.) on your own, you may do your own research here. I will not provide any technical support. As is, it will not quite create assembly perfect for our PCSpim simulator.

Exercise 3: Debugging a MIPS program

Debug the loop in the program in lab10s.s. It is meant to copy integers from memory address $a0 to memory address $a1, until it reads a zero value. The number of integers copied (up to, but not including the zero value), should be stored in $v0.

Exercise 4: Compiling from C to MIPS

The file lab10c.c is a C version of the program in Exercise 3. Using Cygwin (and our cross-compiler), compile this program into MIPS code using the command:

 mips-gcc -S -O2 -fno-delayed-branch lab10c.c

The -O2 (that is capital "o" and the number two) option turns on optimization. The -S (that is capital "s") option generates assembly code. Don't worry about the delayed branch option for now; we will revisit this topic again when we talk about pipelining later this semester.

You are NOT done yet! Read on...

The above command should generate assembly language output (lab10c.s) for the C code. Find the assembly code for the loop that copies sources values to destination values. Then, for the registers $a0, $a1, $v0, and $v1 from part 2, determine what registers gcc used to store the corresponding value. (For example, $a0 was used to store the source address of integers to be copied. What register is used for this purpose in the mips-gcc output?)