Computer Architecture, First Course
Assembly 1: Exercise 2
In these exercises you should become familiar with the following concepts:
- Registers and Arithmetic and Small Constants
- Reading and Writing from Memory
- Branches and Jumps
- Simple String Processing
- 1. Registers, Arithmetic and Small Constants
- 2. Reading and Writing from Memory
- 3. Branches and Jumps
- 4. Simple String Processing
1. Registers, Arithmetic and Small Constants
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 put in $s0; in the second form addi $s0,$s1,12 the constant 12 is added to $s1 and the result is put in $s0. In arithmetic instructions you can only have registers and constants.
1.1. Step 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 instructions. What values do the registers $s0,$s1,$s2,$zero have in them after the code has been executed? What is special about the $zero register?
1.2. Step 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;
2. Reading and Writing from Memory
The MIPS processor has two instructions to read and write values to and from memory. These 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 the distinction between memory locations and values stored in them in mind while you program. You can think of an address as a pointer in C or C++ (if you are familiar with those programming languages).
2.1. Step 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 $ra
Step through the code and examine the contents of the registers and data as the program executes.
- What do you think the two declarations .data and .text are for?
- What do you think the instruction la does? Is it a real instruction what does the assembler actually put in memory?
2.2. Step 2
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.3. Step 3
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($t0) jr $ra
Again step through the code, what values are stored in the registers $s0,$s1,$s2 and why?
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 and test your code.
3. Branches and Jumps
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.
3.1. Step 1
What does the following piece of code do? Again step through the code executing it line by line examining 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 $ra
- 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?
3.2. Step 2
Code the following fragment of pseudo-C in assembler. Verify 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.3. Step 3
Write a routine that adds up all the values in an array. You 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.
4. Simple String Processing
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.
4.1. Step 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 $ra
4.2. Step 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 $ra
4.3. Step 3
Modify the previous program to count the number of space characters. The ASCII code for a space is 32 in decimal or 20 in hexadecimal.
Go back to the Assembly 1 page.