CSCI 255 — Arrays with MIPS32 Assembly

In this lab, you are going to see how arrays are implemented using the MIPS32 instruction set. You may want to use the course MIPS32 reference sheet or the MIPS “Green Card” for this lab. The MPLAB® XC32 Assembler, Linker and Utilities User’s Guide would be the ultimate resource.

Getting Started

Downloading a starter project

Download a tar.gz file or a ZIP file containing a compressed MPLAB X project called ArraysExp. You should be able to extract it from your browser. Be sure to store it in your MPLABXProjects directory.

Using the starter project

Again, start up mplab_ide from either the command line or the launcher.

If you are unsure about how to do this, take a look at the first part of the Introduction to MIPS32 Assembly lab.

Once you have mplab_ide running, open and build the project. (It helps to close all past projects first.)

You can run the program, but it won’t do anything until you go through the next step.

Seeing C output

The simulator tries to be a PIC32 processor, but PIC32 processors aren’t connected to 1280p monitors. If you want to see the output of the printf calls, you have to ask MPLAB X to direct the UART of the chip you are simulating to a window.

You do this in a couple of steps. First, you right-click on the name of your project and select properties. Check the Project Properties window. Make sure that your selected Device is a PIC32MX250F128B.
Project Properties

Now select Simulator under the Categories panel on the left. In the Options for Simulator panel on the right, select Uart2 IO Options under Option categories. Check Enable Uart2 IO and then Apply.
UART 2 I/O Options
This really should already be set, but I just want to make sure you know how to set it in the future.

Start the debugger for your project. If it doesn’t open a window entitled UART 2 Output and display a one-line hello message, something is wrong.
UART 2 output window

Once you get the one-line message, comment out the return after the puts in ExpDriver.c and debug your program again. Be sure to stop the debugger after each time you run it.

Your project and your task

Your project presently has three files.

Be sure you have commented out the first return statement in the main routine. Start the debugger on your code. It should display the following lines.

Problem with return value: 81 != 255
Problem with element 3: 3 != 9
Problem with element 5: 9 != 25
Problem with element 7: 202 != 49

This indicates that the sillyArray doesn’t return the correct value and doesn’t set three array values correctly.

Your task

Open up a window displaying silly.s.

#include    <xc.h>

            .global    sillyArray
            .set       noreorder
            .align     2             # Align on 4-byte boundary
            .ent       sillyArray
            .frame     $sp,0,$ra

# Following MIPS calling conventions, arguments will be as follows:
#   $a0: int *V
#   $a1: int size
#   $a2: int z

# Do the following pointless operators

    # V[7] = 202 ;

    # V[5] = V[3] ;

    # V[z] = z ;

            addi    $v0,$zero,255
    # return v[size-1], that is
    # $v0 = V[size-1]

            jr      $ra
            .end    sillyArray
            .size   sillyArray, .-sillyArray

When this routine is called from main, the three registers $a0, $a1 and $a2 will contain its three arguments. Before this routine returns, with the jr instruction, the return value must be stored in register $v0.

You need to complete the program by writing assembly language statements that correctly implement the three assignment statements and the return statement. The return statement isn’t that hard. Just load the value to be returned in register $v0.

The array index is a little harder. Enlightment is achieved by realizing the equivalence of the following X C expressions when A is an array of 4-byte integers.

Use << 2 rather than * 4 because shifting is faster tham mulitplying. Put the parenthesis around i << 2 because no one teaches precedence rules for shift operators in middle school.

Implement the four C statements in MIPS32 assembly language. Use registers $t0 to $t7 to hold your temporary values.

I suggest you check your progress by writing and testing each statement separately. None of the C statements require more than three MIPS32 instructions for its implementation.

A bit more checking

Just to make sure your code isn’t a bit too specialized, change the calls to sillyArray and sillyArrayInC in ExpDriver.c to have different parameters.

    rca = sillyArray(Xa, XLEN-2,  7) ;
    rcc = sillyArrayInC(Xc, XLEN-2, 7) ;

Run your program with the updated calls.

And one more challenge

Add the following statement to sillayArrayInC, right before the return and then implement the statement in MIPS32 assembly in silly.s .

    V[V[4] & 3] = V[4] ;
If times permits, try this one out.