A Quick Introduction to SPIM

CS 265
George Mason University
D. Nordstrom

What it is

SPIM is an emulator for MIPS RISC computers written by James Larus at the University of Wisconsin. It allows users to run programs written in MIPS RISC assembly language without having access to a computer running a MIPS RISC chip.

There are two versions of SPIM (each is available both for Unix and for PCs). The simplest is a command line version in which you type commands in response to a user prompt (this is the version available here on osf1). The PC version of this can be run in a DOS window. The more elaborate, and much more useful, version of SPIM has a graphical user interface and can be used as a visual debugger as well as for running MIPS programs. Under Unix the graphical user interface version requires X-Windows. The PC version runs under MS Windows.

Getting the Stuff

PC versions of SPIM are available on the web at ftp://ftp.cs.wisc.edu/pub/spim. pcspim.exe is an installer for the MS Windows version and spimdos.exe is an installer for the command line version. spim.tar.gz contains source code which can be used to build Linux versions. The file spim_documentation.ps is a manual for SPIM. This requires access to a postscript printer or to ghostscript. It is strongly recommended that you read that file -- it contains much more information than does this page. The same documentation appears as an appendix to Hennessy and Patterson, Computer Organization and Design (the CS 365 textbook).

Running the Command Line Version

To start the command line version just enter "spim" at the (Unix or DOS) command prompt. You will see a copyright notice and SPIM's user prompt:
C:\asm>spim

SPIM Version 6.0 of July 21, 1997
Copyright 1990-1997 by James R. Larus (larus@cs.wisc.edu).
All Rights Reserved.
DOS and Windows ports by David A. Carley (dac@cs.wisc.edu).
Copyright 1997 by Morgan Kaufmann Publishers, Inc.
See the file README for a full copyright notice.
Loaded: C:/bin/trap.han
(spim) 

You will enter your commands at this prompt. To assemble and load a program use the load command. You must enclose the file name in double quotes. Once the program is loaded you run it with the run command.

(spim) load "greet.asm"
(spim) run
Who are you?  
Marco Polo
Hi there, Marco Polo
(spim) run
Who are you?  
J. S. Bach
Hi there, J. S. Bach
(spim) exit

Of course in real life the first time you try this you get something more like:

(spim) load "error.asm"
spim: (parser) syntax error on line 10 of file error.asm
                l $v0, 4
             ^

When you receive an error message just reedit, reload, and run again. If you modify your program without leaving and restarting SPIM you must reinitialize before reloading:

(spim) load "error.asm"
spim: (parser) syntax error on line 10 of file error.asm
                l $v0, 4
             ^
            (Here I edited and saved "error.asm" from another window.)
(spim) load "error.asm"
spim: (parser) Label is defined for the second time on line 9 of file error.asm
          main:
              ^
          (OOPS!, I reloaded without reinitializing)
(spim) reinitialize
Loaded: C:/bin/trap.han
SPIM Version 6.0 of July 21, 1997
Copyright 1990-1997 by James R. Larus (larus@cs.wisc.edu).
All Rights Reserved.
DOS and Windows ports by David A. Carley (dac@cs.wisc.edu).
Copyright 1997 by Morgan Kaufmann Publishers, Inc.
See the file README for a full copyright notice.
(spim) load "error.asm"
(spim) run
Who are you?  
Thomas Jefferson
Hi there, Thomas Jefferson
(spim)

Debugging from the Command Line Version

SPIM contains limited but extremely useful debugging facilities. You can step through a program one instruction at a time and set breakpoints.

To execute a program one line at a time use the step command. Each time you step SPIM will display a line of your program and execute the displayed instruction. The beginning of the display line is the address of the instruction. The execution will start with several commands prepended to your program by SPIM -- your program instructions will be displayed after SPIM executes "jal main." You do not have to type "step" for each new step. If you hit the enter key SPIM will repeat the last command executed.

As you step through your program you can display register values with the print command. To see the current value in registers $v0 and $a0, for example, enter:

(spim) print $v0
Reg 2 = 0x00000004 (4)
(spim) print $a0
Reg 4 = 0x10010000 (268500992)
Use continue to resume running when you are finished stepping through your program.

You can set breakpoints with the breakpoint command. To do this type either an address (e.g. 0x0040002c) or label (e.g. L1) as an argument (before you can set a breakpoint on a label it must be declared ".globl"). To see what breakpoints are set use the list command and to clear a breakpoint use delete with the address of the breakpoint to be deleted as the argument. If breakpoints are set "running" or "continuing" a program will execute until a breakpoint is reached. You can then step through your program from that point.

Running the GUI Version

The graphical user interface versions of SPIM run under X-Windows on Unix or MS Windows. These programs are nearly identical so we will only describe the MS Windows version here.

After you start SPIM open your source file through the File menu. If your file loads correctly you may (depending on what windows are selected) see a display like Figure 1. If there is an error just reedit and reload.

SPIM for MS Windows
Figure 1. SPIM for MS Windows.

You can open any number of windows through the Window menu. The most useful are the Text Segment window (visible in Figure 1) and the Registers window (Figure 2).

The Registers Window
Figure 2. The Registers Window.

The Text Segment window displays your program source at the far right. Notice that the display begins with several instructions which are start-up code and not part of the program you have written. When you step through your program the current instruction is highlighted. The middle of the display shows your program with pseudo-instructions expanded into true instructionsn. The Registers window shows the current values of all registers. As you step through your program you can view these values changing. It is recommended that you leave these two windows open while you run or debug your program.

To run your program just press the F5 key, or select "Go" from the Simulator menu. SPIM will open a dialogue box to suggest a starting address -- just click OK. As your program runs a Console window will open to display output and accept input from your program.

When your program has finished you can just press F5 to run it again. If you modify your program you will want to open the Simulator menu and select Reload before executing your program.

Debugging is much simpler with the GUI version than with the command line version of SPIM. To step through a program just press F10 or select Single Step from the Simulator window. You will see the current line highlighted in the Text Segment window and the current register values will be visible in the Registers window. To set breakpoints select Breakpoints from the Simulator window. A dialog box will appear (Figure 3) prompting for an address and showing the addresses of all breakpoints currently set. To add a new breakpoint, find the address where you wish to place the breakpoint by locating the proper line in the Text Segment window. The address is the hex number in the far left (not the middle) column. Type this address at the breakpoint prompt. An executing program will stop at each breakpoint on the list.

Setting Breakpoints
Figure 3. Setting Breakpoints.

System Calls

In order to perform simple input and output operations SPIM provides a set of simple system calls. The services, listed in the table below, are accessed by calling syscall with the number of the service in register $v0. Most services require one or more arguments which are placed in registers as described below and some return values in a register.

As an example, to accept a string of at most 20 characters (including newline and 0 terminator) in "buffer" your program would contain:

                .data
buffer: .space 20
        ...
                .text
        ...
                li $v0, 8       # service: read string
                la $a0, buffer
                li $a1, 20
                syscall

SPIM System Services
Service
Number
Arguments
Return Value
print integer
1
$a0 (integer)  
print float
2
$f12 (float)  
print double
3
$f12 (double)  
print string
4
$a0 (address of string)  
read integer
5
  $v0 (integer)
read float
6
  $f0 (float)
read double
7
  $f0 (float)
read string
8
$a0 (address of buffer)
$a1 (bytes allocated for string)
 
sbrk
9
$a0 (integer amount)  
exit
10
   

For the purposes of our course services 1, 4, 5, 8, and 10 will be sufficient.