CSCI 255 preparation
We are making the assumption that you have taken CSCI 255 recently and have completed the lab CSCI 255 — Introducing MPLAB X & PIC assembly. If you haven’t, you may need to do a bit of out-of-lab work or come to lab both weeks.
You can download your own copy of MPLAB X from Microchip’s MPLAB X download page. You will want a copy of the following:
- MPLAB X IDE – v1.90 (or v2.05) is installed in the lab
- MPLAB XC 32 Compiler – v1.22 (or v1.31) is installed in the lab
In CSCI 255 we used the PIC24 processor, but in CSCI 320 we are using the MIPS-based PIC32. You can get a list of MIPS32 instructions from the MIPS32® Instruction Set Quick Reference.
Getting Started
From the command line you can type mplab_ide or you can use your mouse to run MPLAB IDE using the Linux menu selections Applications ⇒ Programming ⇒ MPLAB IDE. (Don’t choose MPLAB IPE.) It may take a little while to start when you first fire up.
First MIPS32 Project in MPLAB X
Creating the project
Use the menu choices File ⇒ New Project... to begin the process of creating a project. Then work your way through a few windows.
- From the Microchip Embedded category choose a Standalone Project.
- Choose the 32-bit MCUs (PIC32) family and then select the first device in the list. (Actually any device will do.)
- Select the Simulator as your hardware tool.
- Select XC32 as your compiler.
- Finally choose a project name, perhaps csci320mipsfun and click Set as main project.
You may have noticed that many of selected choices were preceded by a little green dot. Avoid the ones with the red and yellow dots.
Notice that your project is stored in a directory with names that end with a capital X, such as csci320mipsfun.X .
Checking it out — skip if you took CSCI 255
At this point you have a NetBeans environment that will be familiar to the alumni of CSCI 181 and 202 and (now) 255. Move your mouse over the menu choices at the top of the window, from File to Help. Press on the choices to look at their submenus. Pay particular attention to items under Debug. Most of the choices are presently grayed out, because they can’t be used until you are working on a project.
Notice that the lower left corner is occupied by a Dashboard display. The Microchip PIC devices have very little memory so we need an easy-to-use means of figuring out how much memory our programs are using.
Adding some assembler program
Now we’ll use the menu to create a assembler program. Right click on Source Files then New ⇒ Other... .
- From the Assembler category choose AssemblyFile.s . Be sure to make the .s choice.
- Choose a name for your file. I suggest something like morewhatever. MPLAB X will add the .s suffix to your filename.
At this point, you should have an empty program in the upper-right window. Make sure that your program really is under Source Files.
Copy the following program into your empty window.
## $t0-$t9 temporary registers
## $s0-$s7 saved values
## $a0-$a3 function arguments
## $v0-$v1 return values
## $ra return address
## $sp stack pointer
## $fp frame pointer
#include <xc.h>
## Data is defined here
.data
x: .long 255
## Code is defined here
.global main
.text
.set noreorder
.ent main
main:
addi $sp, $sp, -4
sw $ra, 0($sp)
forever:
lw $t0, x
add $t1, $t0, $t0
add $t0, $t0, $t1
sw $t0, x
j forever
nop
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
nop
.end main
Go ahead and press the hammer to built it, so we can make sure your installation is working.
This program is roughly equivalent to this segment of Java code.
short x = 255 ;
while (true) {
x = 3*x + 1 ;
}
What’s it all about
Like most assembly language programs, this one contains several pseudo-ops or directives. These are lines of code that don’t create instructions.
The program starts with the directive to include the
xc.h, a file containing
definitions of useful constants
for programming PIC microcontrollers. We won’t be doing
that in CSCI 320.
Later you will see directives for defining the
data and text (code) sections for your program.
There is also a line where an integer variable x
is defined and initialized to 255.
Executing a program
The Microchip simulator does know how to simulate the MIPS32 instructions of your program, but all the program does is loop forever. To see anything interesting you must step through the program.
To do this you need to know how to set breakpoints in your program. Now we are going to assume you learned how to set breakpoints in either CSCI 202 or 255. If you haven’t, you may need to review the CSCI 255 lab.
Set the breakpoint at the addi instruction right after the
main label.
Run your program to the breakpoint. If you have done this before using NetBeans, help out any lab neighbors who haven’t.
You will notice a bunch of new tabs in the lower right panel. Take a look at the Variables, CPU Memory and Data Memory tabs. (If you don’t set them, add them.) You’ll find the MIPS32 registers in the CPU Memory tab.
Press the F8 key to step through your program.
Switch between the
Variables and
CPU Memory tabs to see the current
values of x, $t0,
$t1.
If x is being displayed as a 2-byte value,
right-click on the variable name and set its size to 4 bytes.
(I think this could be a bug.)
Step through your program until the variable x is
more than 1000000.
Then keep going until the addition overflows and the simulator
restarts your program at the beginning of main.
To end your debugging session, you can press the little x
on the right lower edge of the screen or type
SHIFT+F5.
Checking the status bits
Oops! There are no status bits in the MIPS32. I must have been thinking about the PIC24 in CSCI 255 for a minute.
Trying out arrays
Yes, it is the same example used in the CSCI 255 lab, but even longer.
Like is CSCI 255, it’s an abbreviated description. Create a MPLAB X project that contains this program.
## $t0-$t9 temporary registers
## $s0-$s7 saved values
## $a0-$a3 function arguments
## $v0-$v1 return values
## $ra return address
## $sp stack pointer
## $fp frame pointer
#include <xc.h>
.equ aSize,100
## Data is defined here
.data
i: .long 0
j: .long 0
V: .fill aSize,4
x: .long 0
y: .long 0
z: .long 0
vSize: .long aSize
## Code is defined here
.global main
.text
.set noreorder
.ent main
main:
addi $sp, $sp, -4
sw $ra, 0($sp)
## initialize V to the first 100 square numbers
lw $t0,vSize ## 100, 99, 98, 97,
la $t1,V ## &V[0], &V[1], &V[2],
add $t2,$0,$0 ## 0, 1, 4, 9, 16, ...
addi $t3,$0,1 ## 1, 3, 5, 7, 9, ...
initloop:
sw $t2,0($t1)
add $t2,$t2,$t3
addi $t3,$t3,2
addi $t1,$t1,4
addi $t0,$t0,-1
bne $t0,$0,initloop
nop
## Your answers should work for these 10 sections of code
## regardless of the initial values of i and j
## sect 0
## x = V[15] ;
## sect 1
## V[17] = -17 ;
## sect 2
## y = V[i] ;
## sect 3
## V[j] = -19 ;
## sect 4
## x = V[i+5] ;
## sect 5
## V[i+j] = -23 ;
## sect 6
## i = (i+j)/2 ;
## sect 7
## V[i] = V[j] ;
## sect 8
## V[16] = V[24] ;
## sect 9
## V[++i] = V[j+=5] ;
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
nop
.end main
The loop at the beginning of the program
initializes the array V to contain the
first 100 squares.
What you are supposed to do
There are ten comments containing short sequences of C/Java code after the loop. See how many of these you can complete.
Remember that the elements of V are four bytes long.
Consider using the SLL instruction for a two-bit shift.