Using the SAL Simulator

Cs 220

Unlike the DOS world, the Unix world rarely provides an integrated development environment, such as Turbo C++. Instead, a text editor is used to produce a file which is passed along to another tool. In this case, the second tool is sal, an abstract MIPS R2000 simulator. sal expects to be given a file containing a SAL assembly language program. You may use your favorite text editor ( emacs, vi, even pico) to create this file in your work directory, which should be a sub-directory of your home directory.

sal provides a few amenities over a bare R2000, such as a facility for setting breakpoints, single-stepping a program, and examining the values of registers and memory locations.

A Skeletal SAL Program

Consider this skeletal program:

# Program documentation goes here.

            .data                         # Constants and variables
                                          # declarations.

            <Constant and variable declarations go here.>

            .text                         # Main (must be global).

__start:    <Your program starts here.>


Running SAL Programs under sal

First, we run a program straight from the shell. Then we run a program from within sal, so that we have the opportunity of setting breakpoints and single-stepping, etc.

The Easy Way to Run a SAL Program

Let's say you have a SAL program in the file SaveTheWorld.sal. Here's the easiest way to run it:

bluebird% sal -file SaveTheWorld.sal
sal will load and execute the program. When execution finishes, you'll be returned to the shell.

Controlling Program Execution from within SAL

From the shell, just type sal. This leaves you at the sal prompt:

bluebird% sal
SPIM Version 4.4.2, Release:  April 22, 1993
Copyright 1990-92 by James R. Larus (
Modified to read SAL code by Scott Kempf (
See the file COPYING for license information
The most important command is help, which prints a summary of all the commands.

To load a program into the simulator, use the load command:

(spim) load "SaveTheWorld.sal"
Note that the program name must be enclosed in quotes.

To run the program, use run:

By default, execution begins with the statement labeled __start.

Debugging SAL Programs

Consider this program fragment:

               .globl i
i:             .word
output:        .word
input:         .word
prompt1:       .asciiz "Enter a number: "
prompt2:       .asciiz "\nOutput: "
nl:            .asciiz "\n"

__start:       move i, 2
               puts prompt1
               get input
               move output, input
               .globl while
while:         blez i, endwhile
               puts prompt1
               get input
               add output, output, input
               sub i, i, 1
               b while
endwhile:      puts prompt2
               put output
               puts nl
If I suspected that I had a problem with my while loop, I would begin debugging it by setting a breakpoint at an appropriate statement, in this case the statement labeled while. Note that I have had to declare while .globl. Breakpoints may only be set at global labels.

After loading the program into memory, I set my breakpoint:

(spim) breakpoint while

When the simulator reaches a statement upon which a breakpoint is set, it suspends execution just before executing the statement. The step command is used to execute one (the default) or more statements at a time. continue is used to resume normal operation. delete label removes breakpoints from the statement labeled label. Hitting the return key at a sal prompt re-executes the last command, so the easiest way to single-step a program is to get to a breakpoint, give a step command, and then start pressing return.

step prints program statements as it executes them. Often, they don't correspond to the assembler program because the simulator converts from SAL to MIPS R2000 machine language. Fortunately, each instruction is labeled with the source instruction from which it originated:

(spim) load "SaveTheWorld.sal"
(spim) step
[0x00400000]     0x34020002  ori $2, $0, 2      # move i, 2
[0x00400004]     0x3c011001  lui $1, 4097       # move i, 2
[0x00400008]     0xac220000  sw $2, 0($1)       # move i, 2
You can see that the SAL instruction move i, 2 is replaced by three MIPS R2000 instructions. This replacement has to be done because the MIPS R2000 has no native move instruction and it is a load/store architecture (Arithmetic/Logic instructions operate on registers. $2, etc., specify registers within the register file.)

Here's how to print the value of a memory location:

(spim) print i
The assumption here is that i is a global label.

Other SAL Commands

exit will terminate sal, returning you to the shell.

If sal seems to go haywire (it does sometimes, after misbehaved programs have been executed or if you load a second program), use reinitialize to restore it to a state of sanity and then load your SAL program.

Thomas P. Kelliher
Thu Sep 18 17:36:02 EDT 1997
Tom Kelliher