CPR E 281x/282x - Lab 9a

 

Introduction to MIPS Assembly Language

 

 

1. Objectives

 

In this lab you will become familiar with the MIPS assembly language.  You will also translate C code into MIPS instructions.

 

1.1           Reference Files for Lab

 

Lab Evaluation Form

 

Lab9a_examples.zip

 

 

2. Prelab

 

Before you come to lab it will be useful to become familiar with the different MIPS assembly instructions.  You will find information in Chapter 2 of your text: “Computer Organization and Design the Hardware/Software Interface” 3rd Edition by Patterson and Hennessy.  Also, there is a good reference guide on the last page and inside the back cover of the textbook.

 

 

3. Setup

 

Download and unzip the Lab 9a files to a Lab9a folder in your home directory, (lab9a_examples.zip).

 

 

4. Using PCSpim

 

You will be using a program called PCSpim to simulate MIPS assembly programs and view what happens to the registers, stack, and data segments.  PCSpim has five windows: Messages, Text Segment, Data Segment, Registers, and a Console.  You will mainly watch the Text Segment which contains the code, the Data Segment which contains stack and data values, and the Registers.  Go ahead and open up PCSpim so you can identify the different windows. 

 

A good reference on assembly and using the Spim simulator is Appendix A of the Hennessy and Patterson textbook, which is available online here.

 

The process for viewing the programs will be the same for each one.  Start by opening an example program.  Then step through the program one instruction at a time by pressing F10.  You will be able to watch the Text Segment window to see what instruction will be executed next.  Then after pressing F10 you can view the changes to the registers in the Registers windows, and view the any changes to the data or stack values in the Data Segment.  You cannot back up a step so if you need to then you will have to reopen the program to restart it.  It is also a good idea to clear the registers (Simulator à Clear Registers) each time you start a new run. 

 

All programs begin with some instructions to initialize the simulator.  To get to the first instruction in the example code, step through the text until you see the instruction jal main in the right column.  The next instruction should be the first one from the example programs.

 

 

5. Understanding Arithmetic Assembly Instructions

 

Begin by starting up the PCSpim program and opening the lab9a_example1.asm program.  Step through the code and fill in the table on the answer sheet for each instruction.  For the register values column fill in the value that are in the registers after executing each instruction.  For the command description column list the complete name of the instruction.  When you are done put the answer to the question on the answer sheet.  Take your time and be sure to understand what is happening with each instruction.  If you have any questions just ask your TA.

 

Example 1:

 

.ent main           # entry at main

 

main:                   # arithmetic instructions

                        # calculate (4((6+2)-(1+2))/2)

 

 addi $16, $zero, 2     # 2

 addi $17, $zero, 6     # 6

 addi $18, $zero, 1     # 1

 add $19, $16, $17      # (6+2)=a

 add $20, $18, $16      # (1+2)=b

 sub $21, $19, $20      # (a)-(b)

 

 add $22, $16, $16      # 4

 mult $22, $21          # 4*(a-b)=c

 mflo $8                # move result (c) to R8

 

 div $8, $16            # c/2

 mflo $9                # move answer to R9

 

 

itself:             # get stuck address

 j itself           # loop here

 

.end                # end program

 

 

Q1:  If the result of the division had a remainder what register is it in?

 

 

6. Understanding Data Transfer and Logical Instructions

 

Begin by starting up the PCSpim program and opening the lab9a_example2.asm program.  Step through the code and fill in the table on the answer sheet for each instruction.  For the register values column fill in the value that are in the registers after executing each instruction.  For the command description column list the instruction name.  When you are done put the answer to the question on the answer sheet.  Take your time and be sure to understand what is happening with each instruction.  If you have any questions just ask your TA.

 

Example 2:

 

.ent main           # entry at main

 

main:                   # data transfer and

                        # logical instructions

 

# data values to load and store

 addi $9, $zero, 3      # set R9 value to 3

 addi $10, $zero, 12    # set R10 value to 12

 

# value = address for data

 lui $8, 0x1000         # set R8 = 0x10000000

 

 sw $9, 0($8)           # store value from R9

 sw $10, 4($8)          # store value from R10

 

 addi $9, $zero, 0      # clear R9

 addi $10, $zero, 0     # clear R10

 

 lw $11, 0($8)          # load value to R11

 lw $12, 4($8)          # load value to R12

 

 or $13, $11, $12       # R11 | R12

 andi $14, $13, 15      # R13 & R9

 srl $16, $12, 2        # shift bits right by 2

 sll $16, $16, 1        # shift bits left by 1

 

 sw $16, 8($8)          # store value from R16

 

 

itself:             # get stuck address

 j itself           # loop here

 

.end               # end program

 

 

Q2:  What is the address where the value from R10 was stored?

 

Q3:  What is the address of the stack pointer ($sp)?

 

 

7. Translating C to Assembly and Understanding Conditional Branch Instructions

 

Begin by starting up the PCSpim program and opening the lab9a_example3.asm program.  Step through the code and fill in the table on the answer sheet for each instruction.   

 

Note: You will only record the values for one loop iteration, but should continue to step through until the program completes.

 

Example 3:

 

.ent main           # entry at main

 

main:                   # C to Assembly translation

                        # conditional branch

# int i = 0;

# int A[16];

#

# while(i <= 15)

# {

#     A[i] = i;

#     i++;

# }

 

 ori $4, $zero, 0xfc    # value to subtract from sp

 sub $sp, $sp, $4       # manipulate stack pointer

 sw $0, 0($sp)          # clear stack location

 sw $0, 4($sp)          # clear stack location

 

 addi $12, $zero, 16    # set R12 to 16

 addi $8, $zero, 0      # clear R8

 add $5, $sp, $zero     # set R5 equal to stack pointer

 

Loop:

 addi $6, $zero, 1      # set R6 to 1

 sw $8, 0($5)           # store R8 in stack

 addi $8, $8, 1         # increment value

 addi $5, $5, 4         # increment stack pointer

 slti $7, $8, 16        # set R7 to 1 if R8 < 16, else 0 

 beq $7, $6, Loop       # conditional branch

 

itself:             # get stuck address

 j itself           # loop here

 

.end               # end program

 

Q4:  Below is what the stack looks like when each byte is incremented and stored.  

 

(Notice the right to left order 0x[00][00][00][00] is four bytes at addresses 0x[7fffef03][7ffef02][7fffef01][7ffef00]).

 

            STACK

[0x7fffef00]                            0x03020100  0x07060504  0x0b0a0908  0x0f0e0d0c

[0x7fffef10]...[0x7ffff000]       0x00000000

 

What is the value stored at the stack address 0x7fffef24 from example 3?

 

Q5:  Just as there is more than one way to write loops in C there is more than one way to write them in assembly.  Often you will want to write efficient code, which means to use the fewest number of instructions, and/or the fewest number of registers.  Rewrite the loop so that it is more efficient, meeting both criteria.