Tutorial 2: More Exercises for the SPIM Simulator
Goal : Become familiar with the following concepts:
- - Registers and Arithmetic and Small Constants
- - Reading and Writing from Memory
- - Branches and Jumps
- - Simple String Processing
Remember MIPS arithmetic instructions come in two forms: for example in the first form add $s0,$s1,$s2 $s1 is added to $s2 and the result is stored in $s0; in the second form addi $s0,$s1,12 the constant 12 is added to $s1 and the result is stored in $s0. In arithmetic instructions, you can only use registers and constants.
- 1. Create the file example1.s as follows then load it into the SPIM simulator.
.text .globl main main: addi $s0,$zero,10 addi $s1,$zero,20 add $s2,$s0,$s1 add $zero,$zero,154 jr $ra
Now step through the program line by line until you reach the jr $ra instruction. What values do the registers $s0,$s1,$s2,$zero have so far? What is special about the zero register?
- 2. Write a complete file that does all of the following calculation:
$s0 = 0 ; $s1 = 76; $s2 = $s1 + 54; $s3 = 104; $s4 = $s3 - $s2 + $s0; $s5 = $s4 - $s1 + 2*$s3;
The MIPS processor has two instructions to read and write values resp. in and from the memory. They are
- - lw $s0,100($s3) which loads into $s0 the value in the memory location $s3 + 100 and
- - sw $s0,100($s3) which stores $s0 into the the memory location $s3 + 100.
You must keep in mind the difference between memory locations and values stored while you are programming. You may think of an address as a pointer in C or C++.
- 1. Create the following file example2.s:
.data n1: .word 10 result: .space 4 .text .globl main main: la $t0,n1 lw $s0,0($t0) addi $s0,$s0,1 sw $s0,0($t0) jr $31
Step through the code and examine the contents of the registers and data as the program executes.
- - What is the use of the two declarations .data and .text?
- - What is the use of the instruction la? Is it a real instruction? what does the assembler actually put in memory?
- - Write a program that swaps around two words of memory. The header should be as follows:
.data n1: .word 10 n2: .word 12 .text .globl main
- Your code should swap around the values stored in n1 and n2. Step through your program to make sure it works.
- 2. Load the following code into the MIPS simulator:
.data vals: .word 10 .word 12 .word 14 .word 56 result: .space 4 .text .globl main main: la $t0,vals lw $s0,0($t0) lw $s1,4($t0) lw $s2,12($s0) jr $31
- Again step through the code, what values are stored in the registers $s0,$s1,$s2 and why?
- 3. In the MIPS processor there is no such instruction as lw $s0,$t0($s1). You have to make such an instruction yourself. By using a combination of an add instruction and a lw instruction write a pair of instructions that loads into $s0 the value stored in the memory location $t0 + $s1. Do the same for sw actually. Test your code.
Normally the MIPS processor simply executes the instructions in order. When it has finished one instruction it simply goes onto the next instruction. Sometimes you want to make decisions based on register values or alter the flow of control of the program. The MIPS processor has two instructions for decision making:
- - bne branch if not equal and
- - beq branch if equal to
and the instruction j label which jumps to the instruction at the label.
- 1. What does the following piece of code do? Again step through the code and examin the contents of the registers.
.text .globl main main: addi $t0,$zero,0 addi $s0,$zero,0 addi $s1,$zero,5 loop: beq $t0,$s1,exit add $s0,$t0,$s0 addi $t0,$t0,1 j loop exit: jr $31
- - What is the function of the register $t0?
- - What is the function of the register $s0?
- - What is the function of the register $s1?
- - What happens if you change the 5 to the value 100?
- 2. Code the following fragment of pseudo-C in assembler. Verify that your code works by stepping through the simulator.
int $s0 = 0; int $s1 = 100; int $t0 = 0; while ($t0 != 10) { $s0 = $s0 + $t0*$t0 ; $t0 = $t0 + 2; }
- 3. Routine that adds up all the values in an array. Your header should look as follows:
.data number: .word 4 #The number of items to sum vals: .word 10 .word 12 .word 14 .word 56 #There must be enough numbers result: .space 4 #This is where the result should go. .text .globl main
The location number should contain the correct number of entries in the array. vals should be the numbers to be summed. You should write the result into result.
A string is an array of bytes. Handling strings is almost as simple as handling arrays of numbers. You have to be a bit careful and load bytes instead of words. A string is normally represented as an array of characters terminated by a '/0' character.
- 1. Run the following piece of code. What happens?
.data str: .asciiz "Hello world." ; .text .globl main main: li $v0,4 la $a0,str syscall jr $31
- 2. What does the following piece of code do? What are the functions of the registers? What does the lb instruction do? What happens if you change it to a lw instruction.
.data str: .asciiz "Hello world." ; .text .globl main main: addi $s0,$zero,0 la $t0,str # $to points to current place in the string. loop: lb $t1,0($t0) beq $t1,$zero,exit addi $s0,$s0,1 addi $t0,$t0,1 j loop exit: jr $31
- 3. Modify the previous program to count the number of space characters. The ASCII code for a space is 32 in decimal or 0x20 in hexadecimal.