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.
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.> doneNotes:
Everything is nicely aligned in columns. A complete program would be extensively commented, because of the low-level nature of assembly language programs. Homework problems which does not follow these guidelines will be returned ungraded (i.e., you will receive no credit).
__start. Labels used for setting breakpoints must be declared global so as to be visible to the simulator:
.text .globl brk1 .globl brk2 __start: <instruction> ... brk1: <instruction> ... brk2: <instruction> ... doneCode must be placed in a .text segment.
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.
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.salsal will load and execute the program. When execution finishes, you'll be returned to the shell.
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 (firstname.lastname@example.org) Modified to read SAL code by Scott Kempf (email@example.com) See the file COPYING for license information (spim)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:
runBy default, execution begins with the statement labeled
Consider this program fragment:
.data .globl i i: .word output: .word input: .word prompt1: .asciiz "Enter a number: " prompt2: .asciiz "\nOutput: " nl: .asciiz "\n" .text __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 doneIf 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 (spim) [0x00400004] 0x3c011001 lui $1, 4097 # move i, 2 (spim) [0x00400008] 0xac220000 sw $2, 0($1) # move i, 2You can see that the SAL instruction
move i, 2is 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 iThe assumption here is that i is a global label.
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.