lecture # 1 spim & mips spim - spim is a self-contained simulator that runs mips32 programs. -...
Post on 07-Feb-2021
Embed Size (px)
Islamic University – Gaza Engineering Faculty
Department of Computer Engineering ECOM 3010: Computer Architecture Discussion
Lecture # 1
SPIM & MIPS Programming
Eng. Nour Eldadah
SPIM - Spim is a self-contained simulator that runs MIPS32 programs.
- It reads and executes assembly language programs written for this processor.
- Spim also provides a simple debugger and minimal set of operating system
QtSpim - The newest version of Spim is called QtSpim, and unlike all of the other
version, it runs on Microsoft Windows, Mac OS X, and Linux—the same source
code and the same user interface on all three platforms!
- QtSpim is the version of Spim that currently being actively maintained. It has a modern user interface, extensive help, and is consistent across all three platforms.
When you open QtSpim, A window will open as shown in Figure 1. The window is
divided into different sections: 1. The Register tabs display the content of all registers.
2. Buttons across the top are used to load and run a simulation
3. The Text tab displays the MIPS instructions loaded into memory to be executed.
(From left-to-right, the memory address of an instruction, the contents of the address in
hex, the actual MIPS instructions – where register numbers are used, the MIPS assembly
that you wrote, and any comments you made in your code are displayed.)
4. The Data tab displays memory addresses and their values in the data and stack
segments of the memory.
5. The Information Console lists the actions performed by the simulator.
Figure 1: QtSpim
MIPS - The MIPS architecture is a Reduced Instruction Set Computer (RISC).
- Each instruction/operation does one thing (memory access, computation,
- In general RISC architectures, and specifically the MIPS architecture, are
designed for high-speed implementations.
MIPS Programming: add.asm We'll write a MIPS assembly language program named add.asm that computes the sum of 1 and 2, and stores the result in register $t0.
- Commenting: Before we start to write the executable statements of program, however, we'll need to write a comment that describes what the program is supposed to do. In the MIPS assembly language, any text between a pound sign (#) and the subsequent newline is considered to be a comment. # add.asm-- A program that computes the sum of 1 and 2, # leaving the result in register $t0. # Registers used: # t0 - used to hold the result. # end of add.asm
- Finding the Right Instructions:
Next, we need to figure out what instructions the computer will need to execute in order to
add two numbers.
We need the add instruction, which adds two numbers together. The add operation takes three operands:
1. A register that will be used to store the result of the addition. For our program, this will
2. A register which contains the first number to be added. Therefore, we're going to have to
get 1 into a register before we can use it as an operand of add. We select $t1, and make
note of this in the comments.
3. A register which holds the second number, or a 32-bit constant. In this case, since 2 is a
constant that fits in 32 bits, we can just use 2 as the third operand of add.
We now know how we can add the numbers, but we have to figure out how to get 1 into register $t1. To do this, we can use the li (load immediate value) instruction, which loads a 32-bit constant into a register. Therefore, we arrive at the following sequence of instructions: # add.asm-- A program that computes the sum of 1 and 2, # leaving the result in register $t0. # Registers used: # t0 - used to hold the result. # t1 - used to hold the constant 1. li $t1, 1 # load 1 into $t1. add $t0, $t1, 2 # $t0 = $t1 + 2. # end of add.asm
- Completing the Program These two instructions perform the calculation that we want, but they do not form a complete program. Much like C, an assembly language program must contain some additional information that tells the assembler where the program begins and ends.
- Labels and main To begin with, we need to tell the assembler where the program starts. In SPIM, program execution begins at the location with the label main. A label is a symbolic name for an address in memory. In MIPS assembly, a label is a symbol name, followed by a colon. Labels must be the first item on a line. Therefore, to tell SPIM that it should assign the label main to the first instruction of our program, we could write the following:
# add.asm-- A program that computes the sum of 1 and 2, # leaving the result in register $t0. # Registers used: # t0 - used to hold the result. # t1 - used to hold the constant 1. main: # SPIM starts execution at main. li $t1, 1 # load 1 into $t1. add $t0, $t1, 2 # $t0 = $t1 + 2. # end of add.asm
- Syscall The way to tell SPIM that it should stop executing your program, and also to do a number of other useful things, is with a special instruction called a syscall. The syscall instruction suspends the execution of your program and transfers control to the operating system. The operating system then looks at the contents of register $v0 to determine what it is that your program is asking it to do.
Table(1) : SPIM Syscalls
In this case, what we want is for the operating system to do whatever is necessary to exit our program. Looking in table 1, we see that this is done by placing a 10 (the number for the exit syscall) into $v0 before executing the syscall instruction. We can use the li instruction again in order to do this , so the last version of the code is : # add.asm-- A program that computes the sum of 1 and 2, # leaving the result in register $t0. # Registers used: # t0 - used to hold the result. # t1 - used to hold the constant 1. main: # SPIM starts execution at main.
li $t1, 1 # load 1 into $t1. add $t0, $t1, 2 # compute the sum of $t1 and 2, and # put it into $t0. li $v0, 10 # syscall code 10 is for exit. syscall # make the syscall. # end of add.asm
1- Click on the “load” button and open add.asm .
Figure (2): add.asm code
2- You can then run the program by simply pressing the “run” (play) button – all instructions will be executed, and the final contents of memory and the register file will be reflected in the QtSpim window as shown in figure 3.
Figure (3): $t0, $t1 registers after run
- Debugging Suppose your program does not do what you expect. What can you do? QtSpim has two features that help debug your program. The first, and perhaps the most useful, is single stepping, which allows you to run your program an instruction at a time. The single
stepping icon can be found in the toolbar. Every time you do single stepping, QtSpim will execute one instruction and update its display, so that you can see what the instruction changed in the registers or memory.
Figure (4): Single Step, after li $t1, 1
Figure (5): Single Step, after add $t0, $t1, 2
What do you do if your program runs for a long time before the bug arises? You could single
step until you get to the bug, but that can take a long time. A better alternative is to use a
breakpoint, which tells QtSpim to stop your program immediately before it executes a
particular instruction. When QtSpim is about to execute the instruction where there is a
breakpoint, it asks for continue, single stepping or abort. Single-stepping and setting
breakpoints will probably help you find a bug in your program quickly. How do you fix it? Go
back to the editor that you used to create your program and change it. Click on the
Riinitialize simulator tab in the toolbar and load the sourcefile again.
Figure(6): Set Breakpoint
Figure(7): After Seting Breakpoint
Figure(8): When reaching Breakpoint
- Generally Useful Information : When using QtSpim, you may find the following information to be useful:
1- You can access all of the commands via the “File” and “Simulator” menus as well.
2- When examining register or memory data, you can view the data in binary, hex, or
decimal format. Just use the “Register” pull down menu to select.
3- To view memory data, simply click on the Data tab.
4- By right clicking on a register file value or memory address value, you can change its contents dynamically.
Second Example: add2.asm For our next example, we'll write a program named add2.asm that computes the sum of two numbers specified by the user at runtime, and displays the result on the screen. The algorithm this program will follow is:
1. Read the two numbers from the user. We'll need two registers to hold these two numbers. We can use $t0 and $t1