Sie sind auf Seite 1von 13

SPIM S20: A MIPS R2000 Simulator

1 th
“ 25 the performance at none of the cost”

James R. Larus
larus@cs.wisc.edu
Computer Sciences Department
University of Wisconsin–Madison
1210 West Dayton Street
Madison, WI 53706, USA
608-262-9519

Modified by Ingrid Zukerman


Faculty of Information Technology
Monash University
Clayton, VICTORIA 3800

c
Copyright 1990–1993 by James R. Larus
(This document may be copied without royalties,
so long as this copyright notice remains on it.)
April 12, 1993
(Revision 11 corresponding to SPIM Version 5.1)

1 Description of the MIPS R2000


MIPS has a RISC (Reduced Instruction Set Computer) architecture. A MIPS processor consists
of an integer processing unit (the CPU) and two coprocessors (Figure 1). Coprocessor 0 handles
exceptions and the memory system. Coprocessor 1 is the floating point unit.
The processor contains 32 general-purpose registers and several special-purpose registers.
MIPS is a load/store architecture, which means that only load and store instructions access
memory. Computation instructions operate only on values in registers.

1.1 Memory Usage


A program’s address space is composed of three parts (Figure 2).

• At the beginning of the user address space (0x00001000) is the text segment, which holds
the instructions for a program.

• After the text segment is the data segment (starting at 0x00002000), which is divided into
two parts.

– Static data – objects whose size and address are known to the compiler and linker.
– Dynamic data – objects for which space is allocated at run time.

• The stack segment resides at the end of the address space (0x00008000). It grows towards
the data segment.

1
Memory

CPU Coprocessor 1 (FPU)


$0
PC $0
Registers
... Registers
...
$31
$31

Multiply
ALU Divide
Arithmetic
FP Unit

Lo Hi

Coprocessor 0
(exceptions and memory)

Figure 1: MIPS R2000 CPU and FPU.

1.2 CPU Registers


The MIPS central processing unit contains 32 general purpose registers that are numbered 0–
31. Register n is designated by $n. Register $0 always contains the hardwired value 0. MIPS
has established a set of conventions as to how registers should be used. These suggestions are
guidelines, which are not enforced by the hardware. Table 1 lists the registers and describes
their intended use. A register may be addressed either by its name or by its number.

• Registers $at (1), $k0 (26), and $k1 (27) are reserved for use by the assembler and oper-
ating system.

• Registers $a0–$a3 (4–7) are used to pass the first four arguments to routines (remaining
arguments are passed on the stack).

• Registers $v0 and $v1 (2, 3) are used to return values from functions.

• Registers $t0–$t9 (8–15, 24, 25) are caller-saved registers used for temporary quantities
that do not need to be preserved across calls.

• Registers $s0–$s7 (16–23) are callee-saved registers that hold long-lived values that should
be preserved across calls.

2
(0 K) 0x00000000
Reserved

(4 K) 0x00001000
Text Segment

(8 K) 0x00002000
Data Segment

(16 K) 0x00004000

Stack Segment

(32 K) 0x00008000

Figure 2: Layout of memory.

• Register $sp (29) holds the stack pointer, which points to the last used location on the
stack.

• Register $fp (30) holds the frame pointer.

• Register $ra (31) holds the return address for a call made by the jal instruction.

• Register $gp (28) holds a global pointer that points into the middle of an 8K block of
memory that holds constants and global variables.

1.3 Calling Convention


A stack frame consists of the memory starting at the arguments passed to a callee (arg n ) and
ending at the stack pointer ($sp) (Figure 3). As typical of Unix systems, the stack grows down
from higher memory addresses, so the frame pointer points to a memory address that is higher
than or equal to the address pointed to by the stack pointer.
The following steps are necessary to effect a call:

1. Save the registers the caller wants preserved across the call. By convention, this may
include registers $t0–$t9 and $s0–$s7.

2. Pass the arguments. By convention, the first four arguments are passed in registers $a0–
$a3. However, space is reserved on the stack for these arguments. The contents of these
registers are put on the stack later on if the callee needs to change their value. The
remaining arguments are pushed on the stack.

3. Execute a jal instruction.

The stack resulting from these steps appears in Figure 3(b).


Within the called routine, the following steps are necessary:

1. Push the return address in register $ra on the stack.

3
(a) Stack prior to saving registers (b) Stack prior to procedure entry (c) Stack after procedure entry
and pushing parameters onto stack Parameters pushed onto stack New frame established

the stack. The stack pointer points to the last word in the frame.
Figure 3: Layout of a stack frame. The frame pointer points to the old frame pointer saved on
Address 0 Address 0 Address 0

$sp
first local variable

...

last local variable

old frame pointer


$fp
return address
$sp New
arg 1 Stack arg 1
frame
arg 2 arg 2

New ... ...


Stack
frame arg n-1 arg n-1
4

arg n arg n

saved register x saved register x


saved regs saved regs
... to restore ... to restore
Old on return on return
Stack saved register y saved register y
frame Old
$sp Stack
local frame old local
local
variables variables
variables
Old
Stack $fp
original frame pointer original frame pointer original frame pointer
frame $fp
return address return address return address

.. ...
.. ... .. ...
. . .
Stack start Stack start Stack start
Register Name Number Usage
zero 0 Constant 0
at 1 Reserved for assembler
v0 2 Expression evaluation and
v1 3 results of a function
a0 4 Argument 1
a1 5 Argument 2
a2 6 Argument 3
a3 7 Argument 4
t0 8 Temporary (not preserved across call)
t1 9 Temporary (not preserved across call)
t2 10 Temporary (not preserved across call)
t3 11 Temporary (not preserved across call)
t4 12 Temporary (not preserved across call)
t5 13 Temporary (not preserved across call)
t6 14 Temporary (not preserved across call)
t7 15 Temporary (not preserved across call)
s0 16 Saved temporary (preserved across call)
s1 17 Saved temporary (preserved across call)
s2 18 Saved temporary (preserved across call)
s3 19 Saved temporary (preserved across call)
s4 20 Saved temporary (preserved across call)
s5 21 Saved temporary (preserved across call)
s6 22 Saved temporary (preserved across call)
s7 23 Saved temporary (preserved across call)
t8 24 Temporary (not preserved across call)
t9 25 Temporary (not preserved across call)
k0 26 Reserved for OS kernel
k1 27 Reserved for OS kernel
gp 28 Pointer to global area
sp 29 Stack pointer
fp 30 Frame pointer
ra 31 Return address (used by function call)

Table 1: MIPS registers and the convention governing their use.

2. Push the old frame pointer (currently in register $fp) on the stack.

3. Assign the current top-of-stack address to the frame pointer (in register $fp).

4. Allocate on the stack space for local variables by subtracting the number of words they
require from the stack pointer, and assigning the result to register $sp.

The stack resulting from these steps appears in Figure 3(c).


Finally, to return from a call, a function executes the following steps:

1. Place the returned value into $v0 (and $v1 if necessary).

2. Restore to register $ra the return address which is stored in memory location $fp + 4.

3. Pop the stack by assigning $fp + 8 to register $sp. This points the stack pointer to the
memory location of arg1 .

4. Restore the frame pointer in register $fp by assigning to it the old value of the frame
pointer, which resides in the memory location stored in register $fp.

5
5. Return by jumping to the address in register $ra.

Now we have returned to the calling program, which performs the following steps:

1. Pop the arguments off the stack by making the stack pointer point to the last saved register.

2. Restore any registers that were saved upon entry, and pop the stack to the original position.

The stack resulting from these steps appears in Figure 3(a).

2 SPIM
SPIM S20 is a simulator that runs programs for the MIPS R2000/R3000 RISC. 1 SPIM can read
and immediately execute files containing assembly language or MIPS executable files. SPIM is
a self-contained system for running these programs and contains a debugger and interface to a
few operating system services.
You can download the SPIM simulator from: http://www.cs.wisc.edu/~larus/spim.html

2.1 Why Use a Simulator?


An obvious question is: why use a simulator when many people have workstations that contain
a hardware, and hence significantly faster, implementation of this computer? One reason is
that these workstations are not generally available. Another reason is that these machines will
not persist for many years because of the rapid progress leading to new and faster computers.
Unfortunately, the trend is to make computers faster by executing several instructions concur-
rently, which makes their architecture more difficult to understand and program. The MIPS
architecture represents a simple, clean RISC machine.
In addition, simulators can provide a better environment for low-level programming than an
actual machine because they can detect more errors and provide more features than an actual
computer. For example, SPIM has an X-window interface that is better than most debuggers
for the actual machines.
Finally, simulators are a useful tool for studying computers and the programs that run on
them. Because they are implemented in software, not silicon, they can be easily modified to add
new instructions, build new systems such as multiprocessors, or simply to collect data.

2.2 SPIM Interface


To run SPIM in Linux you need to simply type xspim; in Windows click on PCSpim.
The Linux version of SPIM has five panes (Figure 4). The Windows version has four panes;
the control buttons in the second Linux pane described below appear in a drop-down menu from
the Simulator label (top of the window).
The top pane displays the contents of the registers. It is continually updated, except while
a program is running.
The next pane in the Linux version contains the buttons that control the simulator (drop-
down menu in Windows):

quit
Exit from the simulator.

load
Read an assembly language file into memory.
1
For a description of the real machines, see Gerry Kane and Joe Heinrich, MIPS RISC Architecture, Prentice
Hall, 1992.

6
Figure 4: X Windows interface to SPIM.

7
reload
Reinitialize memory and registers, and read the previously loaded file into memory.

run
Start the program running.

step
Step through a program (each step may be composed of one or more instructions).

clear
Reinitialize registers or memory.

set value
Set the value in a register or memory location.

print
Print the value in a register or memory location.

breakpoint
Set or delete a breakpoint or list all breakpoints.

help
Print a help message.

terminal
Raise or hide the console window.

mode
Set SPIM operating modes. The quiet mode does not report exceptions. The bare mode
does not provide the additional addressing modes provided by the assembler (Table 3).

The next two panes display the memory contents. The top one shows instructions from the
user and kernel text segments.2 The first few instructions in the text segment are startup code.
The lower of these two panes displays the data and stack segments. Both panes are updated
as a program executes.
The bottom pane is used to display messages from the simulator. It does not display output
from an executing program. When a program reads or writes, its I/O appears in a separate
window, called Console, which pops up when needed.

2.3 Assembler Syntax


Comments in assembler files begin with a sharp-sign (#). Everything from the sharp-sign to
the end of the line is ignored.

Identifiers are a sequence of alphanumeric characters, underbars ( ) and dots (.) that do not
begin with a number.

Operation codes (opcodes) for instructions are reserved words that are not valid identifiers
(the Appendix has a list of these opcodes).

Labels are declared by putting them at the beginning of a line followed by a colon.

The code is divided into two segments .data and .text. The first instruction in the .text
segment must be labelled main.
2
Each source instruction appears as a comment on the first instruction to which it is translated.

8
Service Call Code Arguments Result
print int 1 $a0 = integer
read int 5 integer (in $v0)
exit 10

Table 2: System services.

Example:

.data # indicates the beginning of the data


item: .word 1 # stores the number 1 in a memory word labelled "item"
.text # indicates the beginning of the program
main: lw $t0, item # load the word in item into register $t0

SPIM supports a subset of the assembler directives provided by the MIPS assembler:

.asciiz str
Store the string in memory and null-terminate it.

.byte b1, ..., bn


Store the n values in successive bytes of memory.

.data <addr>
The following data items should be stored in the data segment. If the optional argument
addr is present, the items are stored beginning at address addr .

.space n
Allocate n bytes of space in the current segment (which must be the data segment in
SPIM).

.text <addr>
The next items are put in the user text segment. In SPIM, these items may only be
instructions or words (see the .word directive below). If the optional argument addr is
present, the items are stored beginning at address addr .

.word w1, ..., wn


Store the n 32-bit quantities in successive memory words.

2.4 System Calls


SPIM provides a small set of operating-system-like services through the system call (syscall)
instruction. To request a service

1. put the system call code (Table 2) in register $v0, and

2. put the argument(s) in register $a0, and $a1 if necessary.

System calls that return values put their result in register $v0.

print int is passed an integer (in $a0) and prints it on the console.

read int reads an entire line of input up to and including the newline. Characters following
the number are ignored. The result is placed in $v0.

exit stops a program from running.

9
3 Very Reduced Instruction Set
In all the instructions below, Rsrci is a register, and Imm an immediate value (a 16 bit integer).

3.1 Arithmetic Instructions

add Rdest, Rsrc1, Rsrc2 Addition (with overflow)


addi Rdest, Rsrc1, Imm Addition Immediate (with overflow)
Put the sum of the integers from register Rsrc1 and Rsrc2 (or Imm) into register Rdest.

div Rsrc1, Rsrc2 Divide (with overflow)


Divide the contents of register Rsrc1 by those of Rsrc2. Leave the quotient in register Lo and
the remainder in register Hi. If an operand is negative, the result is unspecified in SPIM, and
depends on the machine on which SPIM is run.

mult Rsrc1, Rsrc2 Multiply


Multiply the contents of the two registers. Leave the low-order word of the product in register
Lo and the high-order word in register Hi.

sub Rdest, Rsrc1, Rsrc2 Subtract (with overflow)


Put the difference of the integers from register Rsrc1 and Rsrc2 into register Rdest.

3.2 Data Movement Instructions


The multiply and divide instructions put their result in two additional registers, Hi and Lo. The
following instructions move values from these registers.

mfhi Rdest Move From Hi


mflo Rdest Move From Lo
Move the contents of the Hi (Lo) register to register Rdest.

3.3 Logical Instructions

and Rdest, Rsrc1, Rsrc2 AND


andi Rdest, Rsrc1, Imm AND Immediate
Put the logical AND of the integers from register Rsrc1 and Rsrc2 (or Imm) into register Rdest.

nor Rdest, Rsrc1, Rsrc2 NOR


Put the logical NOR of the integers from register Rsrc1 and Rsrc2 into register Rdest.

or Rdest, Rsrc1, Rsrc2 OR


ori Rdest, Rsrc1, Imm OR Immediate
Put the logical OR of the integers from register Rsrc1 and Rsrc2 (or Imm) into register Rdest.

xor Rdest, Rsrc1, Rsrc2 XOR


xori Rdest, Rsrc1, Imm XOR Immediate
Put the logical XOR of the integers from register Rsrc1 and Rsrc2 (or Imm) into register Rdest.

10
Format Address Computation
(register) contents of register
Imm immediate (actual value)
[−]Imm(register) [−]immediate + contents of register
symbol address of symbol
symbol+[−]Imm address of symbol + [−]immediate
symbol+[−]Imm(register) { address of symbol + contents of register } + [−]immediate

Table 3: Addressing modes.

3.4 Shift Instructions

sll Rdest, Rsrc1, Imm Shift Left Logical


sllv Rdest, Rsrc1, Rsrc2 Shift Left Logical Variable
sra Rdest, Rsrc1, Imm Shift Right Arithmetic
srav Rdest, Rsrc1, Rsrc2 Shift Right Arithmetic Variable
srl Rdest, Rsrc1, Imm Shift Right Logical
srlv Rdest, Rsrc1, Rsrc2 Shift Right Logical Variable
Shift the contents of register Rsrc1 left (right) by the distance indicated by Imm (the contents
of Rsrc2) and put the result in register Rdest. The arithmetic shift replicates the sign, while
the logical shift replaces it with 0.

3.5 Load and Store Instructions


The machine provides the addressing modes in Table 3 for load and store instructions:

lw Rdest, address Load Word


Load the 32-bit quantity (word) at address into register Rdest.

sw Rsrc, address Store Word


Store the word from register Rsrc into address.

3.6 Comparison Instructions

slt Rdest, Rsrc1, Rsrc2 Set Less Than


slti Rdest, Rsrc1, Imm Set Less Than Immediate
Set register Rdest to 1 if register Rsrc1 is less than Rsrc2 (or Imm) and to 0 otherwise.

3.7 Control Transfer Instructions


Branch instructions use a signed 16-bit offset field; hence they can jump 2 15 −1 instructions (not
bytes) forward or 215 instructions backwards. The jump instruction contains a 26 bit address
field.

beq Rsrc1, Rsrc2, label Branch on Equal


Conditionally branch to the instruction at label if the contents of register Rsrc1 equals the
contents of register Rsrc2.

bne Rsrc1, Rsrc2, label Branch on Not Equal


Conditionally branch to the instruction at label if the contents of register Rsrc1 are not equal
to the contents of register Rsrc2.

11
j label Jump
Unconditionally jump to the instruction at label.

jal label Jump and Link


Unconditionally jump to the instruction at label. Save the address of the next instruction in
register $ra (31).

jr Rsrc Jump Register


Unconditionally jump to the instruction whose address is in register Rsrc.

3.8 System Calls

syscall System Call


Register $v0 contains the number of the system call provided by SPIM (Table 2).

3.9 Pseudo-instructions
Instructions that expand to short sequences of MIPS instructions. For example, the pseudo-
instruction blt $t2, $t3, label (branch-less-than) is expanded to:

slt $t1, $t2, $t3


bne $t1, $0, label

12
Appendix: Opcodes (Cannot be Used as Labels)
Common Opcodes
.align .ascii .asciiz .data .byte .double
.end .extern .float .globl .text .word
add addi addiu addu and andi
b bal beq bge bgeu bgez
bgezal bgt bgtu ble bleu blez
blt bltu bltz bne bnez break
div divu j jal jalr jr
la lb lbu ld lh lhu
lui lw lwl lwr mfhi mflo
mul mult neg negu nop nor
or ori rem remu rol sb
sd seq sge sgt sgtu sh
sle sleu sll slt slti sltiu
sltu sne sra srav srl srlv
sub subu sw swl swr syscall
usw xor xori

Unusual Opcodes
.asm0 .bgnb .endb .endr .ent .file
.fmask .frame .kdata .ktext .lab .lcomm
.livereg .loc .noalias .option .rdata .repeat
.sdata .set .struct .verstamp .vreg
abs abs.s add.d add.s bc0f bc0t
bc1t bc2f bc2t bc3f bc3t c.eq.d
c.eq.s c.f.d c.le.d c.le.s c.lt.d c.lt.s
c.nge.d c.nge.s c.ngl.s c.ngle.d c.ngle.s c.ngt.d
c.ngt.s c.ole.d c.olt.d c.olt.s c.seq.d c.seq.s
c.sf.d c.sf.s c.ueq.s c.ule.d c.ule.s c.ult.d
c.ult.s c.un.d cfc0 cfc1 cfc2 cfc3
cop0 cop1 cop3 ctc0 ctc1 ctc2
ctc3 cvt.d.s cvt.s.d cvt.s.w cvt.w.d cvt.w.s
div.d l.d li.d li.s lwc0 lwc1
lwc3 mfc0 mfc1 mfc1.d mfc2 mfc3
mov.d mov.s mtc0 mtc1 mtc1.d mtc2
mtc3 mthi mtlo mul.d mul.s mulo
mulou neg.d neg.s rfe s.d s.s
sub.d sub.s swc0 swc1 swc2 swc3
tlbp tlbr tlbwi tlbwr ulh ulhu
ush

13

Das könnte Ihnen auch gefallen