Spim as Intermediate code
This document describes the subset of Spim that you are going
to use for your intermediate code.
Examples of spim programs using this subset can be found on
the website for the course. For information about other features
of Spim see the complete document, also online.
- We are only going to use temporary registers $t0 - $t7
- All data is going to be stored in word size (32 bit) locations.
- Data manipulations are always done on registers.
- Comments start with # and go to the end of the line.
- Data and code are marked using the .data and .text
directives, respectively. Be sure that in your generated code, the
data labels appear in a .data section and that intermediate
code and labels for control flow appear in a .text section.
.data
item: .word 1 # allocate a word of memory, initial value 1
arr: .word 0,0,0,0,0 # allocate 5 words of memory, initial value 0
.text
main: lw $t0,item
. . .
The above code allocates a word for
variable item with initial value 1 and 5 words for arr.
Addressing Modes:
Spim allows various addressing modes, a subset of which we can
use during intermediate code generation
Format | Address Computation |
register | indicates the register |
(register) | contents of the register |
imm | immediate value |
imm(register) | immediate value + contents of register |
symbol | address of symbol |
Instructions
- Data Movement
- lw temp, var -- copies memory value stored at var into register temp
- li temp, number -- copies given number into register temp
- la temp, var -- loads the address of var
into register temp
- sw temp, var -- copies temp register contents into a memory
location var
- move temp1,temp2 -- copy the contests of temp2
to temp1.
- Arithmetic
- add temp1, temp2, temp3 -- added the contents of registers
temp2 and temp3, storing the result in temp1.
- sub temp1, temp2, temp3 -- subtracts the contents of register
temp3 from temp2, storing the result in temp1.
- mul temp1, temp2, temp3 -- multiplies the contents of registers
temp2 and temp3, storing the result in temp1.
- div temp1, temp2, temp3 -- divides the contents of register
temp3 into temp2, storing the result in temp1.
- neg temp1, temp2 -- negate the contents of register
temp2, storing the result in temp1.
- Comparison
- seq temp1, temp2, temp3 -- Set register temp1 to 1 if contents of register temp2 equals contents of register temp3, 0 otherwise
- sge temp1, temp2, temp3 -- Set register temp1 to 1 if contents of register temp2 is greater than or equal contents of register temp3, 0 otherwise
- sgt temp1, temp2, temp3 -- Set register temp1 to 1 if contents of register temp2 is greater than contents of register temp3, 0 otherwise
- sle temp1, temp2, temp3 -- Set register temp1 to 1 if contents of register temp2 is less than or equal contents of register temp3, 0 otherwise
- slt temp1, temp2, temp3 -- Set register temp1 to 1 if contents of register temp2 is less than contents of register temp3, 0 otherwise
- sne temp1, temp2, temp3 -- Set register temp1 to 1 if contents of register temp2 is not equal contents of register temp3, 0 otherwise
- Branching
- b label -- unconditionally branch to the instruction at
the label.
- beqz temp, label -- branch to the instruction at
the label if the contest of temp equals 0.
- bnez temp, label -- branch to the instruction at
the label if the contest of temp does not equal 0.
- jal label -- unconditionally jump to the instruction
at label. Save the address of the instruction following
the jump in register 31 ($ra).
- jr temp -- unconditionally jump to the instruction
at the address stored in register temp
- System Services (i/o). The following shows the instructions required
to read and print integers, as well as designate the termination of the
program.
- Printing integers:
li $v0,1 # system code for printing integers placed into v0
li $a0,5 # load the integer into register a0. This instruction
# could also be a move or lw into a0.
syscall # print it
- Reading integers:
li $v0,5 # system code for reading integers placed into v0
syscall # read it
sw $v0,x # move the integer into new location. This instruction
# could also be a move from v0 into a register.
Using the Spim Interpreter
The spim interpreter comes both in a command line format (spim) and
in a X-window interface (xspim), both of which are installed
on osf1. Complete descriptions of the use of these
tools is found in the online spim documentation. This brief description
only outlines the minimum stuff you need to know to use the X-window
version.
The interface is fairly self-explanatory, however you will probably
only need to use a few of the buttons.
- quit
- load -- provide a file name to load into the simulator. If there
are syntax problems with the file, that information appears in the
bottom window. As you might expect, your spim code will not run
with syntax errors.
- run
- clear -- If you need to load or reload a new file into the
simulator, it is a good idea to clear out the memory and registers
to be sure nothing remains of the old program to cause problems. If
you want to run a loaded program again, use clear to clear out
the registers so that old information is not used.