Getting Started
- Overview
- Text Editors for MIPS Assembly
- SPIM Installation
- Running MIPS programs on SPIM
- Basic Debugging Skills
- Common SPIM Problems
- Common MIPS Errors
Overview
Although there are several MIPS simulators/emulators, we will use SPIM in this course. SPIM is a simple MIPS simulator/emulator. It reads MIPS assembly language programs, then assembles and executes them.
Here are some useful resources about MIPS and SPIM:
- A Quick MIPS Reference Card
- Assemblers, Linkers, and the SPIM Simulator: A very good introduction to MIPS assembly programming which also includes detailed documentation for the MIPS R2000 assembly language instruction set.
- SPIM original documentation if you are interested to know more about this MIPS simulator.
spim
terminal interface guidespim
command line guide- MIPS Instruction Reference
- MIPS Pseudo-Instructions
LC-3 is optional, here are some useful resources if you want to learn more abouyt LC-3 programming (including manuals and simulators/emulators):
- LC-3 Assembly Language Manual
- LC-3 ISA
- LC-3 Unix Simulator
- LC-3 Windows Simulator
- C to LC-3 compiler
Here are some useful notes regarding computer architecture:
Text Editors for MIPS Assembly
Visual Studio Code
In Visual Studio Code, open the quick-open (Ctrl+P) and type
ext install kdarkhan.mips
. Like Atom’s and Sublime Text’s support,
this is based on the TextMate syntax bundle.
Sublime Text
In PackageControl, install “MIPS Syntax”, which corresponds to github:contradictioned/mips-syntax. Like Atom’s and VSCode’s support, this is based on the TextMate syntax bundle.
Atom
Install atom:language-mips, by going to Edit ▷ Preferences ▷ Install, and searching for the package. Like Sublime Text’s and VSCode’s support, this is based on the TextMate syntax bundle.
Vim
A few good options exist for Vim syntax files. We suggest
github:harenome/vim-mipssyntax.
Add the mips.vim
language file from that repository to your
~/.vim/syntax
, or if you use Pathogen, add the repository to your set
of bundles.
Emacs
GNU Emacs’ asm-mode works great for writing assembly. It will
automatically ensure your operands, comments, and labels are correctly
aligned — but beware, it assumes that ;
, //
, or /*
…*/
indicate
comments, which is not the case for SPIM.
On some machines, files with a .s
extension are assumed to be for a statistics
language in the S family (e.g., R), and will start in ESS mode. You’ll
need to explicitly flip into asm-mode, by running M-x asm-mode, or
change your auto-mode-alist.
SPIM Installation
There are three ways to execute MIPS code with SPIM:
spim
command line tool- load programs using
-file
option - interact using stdin/stdout via login terminal
- load programs using
qtspim
GUI environment- load programs via a load button
- interact via a pop-up stdin/stdout terminal
xspim
GUI environment- I do not recommend using this version
- requires
X-windows
server
On MacOS you can install spim
using homebrew
:
$ brew install spim
If you want to set up qtspim
on your own computer, download it from spimsimulator.sourceforge.net, or from one of these links:
-
Download for Windows (.msi)
(QtSpim_9.1.21_Windows.msi) -
Download for macOS (.pkg)
(QtSpim_9.1.21_mac.pkg) -
Download for Linux (64-bit .deb)
(qtspim_9.1.22_linux64.deb) -
Download source
(spim-simulator-spim-pkg.tar.gz)
For Windows, run the .MSI installer bundle, which will set up QtSPIM for you.
For macOS, run the .PKG installer bundle, which will set up QtSPIM for you.
For 64-bit Debian Linux, including Ubuntu and Mint, install the .deb file, which will set up QtSPIM for you.
Building your own SPIM
On other platforms, you may need to compile from source.
We suggest the patched version of SPIM, linked above. You’ll need CMake, a C/C++ compiler, flex, and bison; if you want QtSPIM, you’ll need Qt development files installed. These should be available from your package manager.
$ apt install cmake gcc flex bison lib{xt6,xaw7}-dev qtbase5-dev
Extract the tarball
$ tar -xzf spim-simulator-spim-pkg.tar.gz
$ cd spim-simulator-spim-pkg
And run CMake to configure, build, and install SPIM. You should probably set the value of CMAKE_INSTALL_PREFIX
to your home directory, which we do here; by default, it will install into /usr/local
, so the installation may need administrative permissions.
$ cmake -S . -B obj -D CMAKE\_INSTALL\_PREFIX=$HOME
$ cmake --build obj
$ cmake --build obj -t install
[... some output, ending in ...]
-- Install configuration: ""
-- Installing: $HOME/share/spim/exceptions.s
-- Installing: $HOME/share/spim/helloworld.s
-- Installing: $HOME/bin/spim
-- Installing: $HOME/bin/xspim [if X11 was found\]
-- Installing: $HOME/bin/qtspim [if Qt was found\]
If all went well, you should now be able to run the spim
or qtspim
commands.
If you have questions, please ask on the course forum, and we’ll try and help you out.
Running MIPS programs on SPIM
These steps show how to run a MIPS program on SPIM. After completing these steps look at the Basic Skills section to learn techniques useful for debugging.
- Load a MIPS assembler file (e.g., hello.s) into your editor. The MIPS instructions should be highlighted appropriately if you have setup the syntax highlighters appropriately.
- Start the simulator either with
qtspim
(graphical interface tool) orspim
(command line tool). You should be able to see the register values, the program in binary and assembler forms, the data area, and messages. - Check the bottommost pane for error messages. It may be necessary to make other panes smaller to see the bottommost pane. If there are any errors fix them, exit the simulator and restart!
- Run the program by clicking the run button. If the program generates output a window entitled SPIM Console should pop up. If you don’t see it try moving the simulator window. Use the arrow keys to scroll within the SPIM Console window.
- If you’re satisfied with the output then you’re done, otherwise edit the MIPS program and try again. See the Basic Skills section for some debugging techniques.
Basic Debugging Skills
Students should have the following basic debugging skills before attempting a homework assignment.
-
Single-Step Execution: Do this by clicking
step
in the main SPIM window then clickingstep
in the small dialog that pops up. Each press of step will advance execution by one instruction, this can be seen by the movement of highlighting in theText Segments
pane. - Determine Register and Memory Values:
The main SPIM window shows register values. Memory values are shown in the
Data Segments
pane. To find the address of the data you are interested find ala
pseudo-instruction that loads the address of that data. - Set a Breakpoint:
Single-stepping is a pain if you need to execute hundreds of
instructions before execution reaches the instruction you’re
interested in. If this applies to you, find the address of the
instruction by scrolling the
Text Segments
pane until your instruction is visible; the address is the first hexadecimal number. Then select breakpoints and enter the address. - Find Documentation: Many errors are due to the incorrect usage of an instruction. Looking up an instruction should be quick and easy, so set a bookmark on your favorite browser or otherwise provide one-click access to the instruction documentation
Common SPIM Problems
The following problems are frequently encountered when using SPIM.
- Syntax and Other Assembly Errors When you start SPIM look for errors on the bottommost pane.
- Program Does not Seem to Run
In the run or step dialog the staring address should be about
0x00400000. If the starting address is zero then SPIM could not find
the
main:
symbol that should appear before the routine that is to run first. Make sure there are no errors that are confusing SPIM before it reachesmain:
. - Stack Overflow Error Most likely due to an infinite recursion error. A recursive procedure needs to test some kind of no-more-recursion condition before making a recursive call. If this condition is always false then recursion will be infinite and stack space will be exhausted.
- Address Errors
A zero or other invalid address is often due to common programming
errors, such as never setting a register to an address in the first
place. A misaligned address occurs when a
lw
orsw
instruction is executed with an address that’s not a multiple of 4, or forlh
, etc., a multiple of 2.
Common MIPS Errors
The following are common errors in MIPS programs.
- Unintended Instruction in Delay Slot
#
# Example Error:
#
addi $a0, $a0, 4
j SOMEWHERE
# Okay, here I do something else.
ELSEWHERE:
add $a0, $t0, $s1
#
# Code with Error Fixed:
#
addi $a0, $a0, 4
j SOMEWHERE
nop # Or any other instruction relevant to your program
# Okay, here I do something else.
ELSEWHERE:
add $a0, $t0, $s1
In the first code fragment above the add \$a0, \$t0, \$s1
is executed even though the jump is taken.
- Wrong Data Type Size
#
# Example Error
#
lw $t0, 0($a0)
addi $a0, $a0, 1
lw $t1, 0($a0)
# Correct Code
lw $t0, 0($a0)
addi $a0, $a0, 4
lw $t1, 0($a0)
- Program Does Not Work Properly, For Some Reason To debug a program find the point at which it stops doing what was intended. To do this you need to know what the program should be doing, so review the algorithm and work out a bit by hand. You should also be able to single step, set SPIM breakpoints, and examine register and memory values. Simple errors can be caught by reviewing the code, but in more complex programs there is no substitute for watching what happens when it runs.