COE301 Lab 2 Introduction MIPS Assembly
COE301 Lab 2 Introduction MIPS Assembly
2 Assembly Programming
2.1 Objectives
# Title:
# Author:
# Date:
# Description:
# Input:
# Output:
################### Data segment #####################
.data
. . .
################### Code segment #####################
.text
.globl main
main: # main function entry
. . .
li $v0, 10
syscall # system call to exit program
.data Defines the data segment of the program, containing the program’s variables.
.text Defines the code segment of the program, containing the instructions.
.globl Defines a symbol as global that can be referenced from other files.
2. Executable Instructions: These generate machine code for the processor to execute at runtime.
Instructions tell the processor what to do.
3. Pseudo-Instructions and Macros: Translated by the assembler into real instructions. These
simplify the programmer task.
In addition there are comments. Comments are very important for programmers, but ignored by the
assembler. A comment begins with the # symbol and terminates at the end of the line. Comments
can appear at the beginning of a line, or after an instruction. They explain the program purpose,
when it was written, revised, and by whom. They explain the data and registers used in the program,
input, output, the instruction sequence, and algorithms used.
Before you can run a MIPS program, you must convert the assembly language code into an
executable form. This involves two steps:
1. Assemble: translate the MIPS assembly language code into a binary object file. This is done by
the assembler. If there is more than one assembly language file, then each should be assembled
separately.
2. Link: combine all the object files together (if there is more than one) as well as with libraries.
This is done by the linker. The linker checks if there are any calls to functions in libraries. The
result is an executable file.
Figure 2.2 summarizes the Edit-Assemble-Link-Run cycle of the program development process. If a
program is written in assembly language, the assembler detects any syntax errors and will report
them to the programmer. Therefore, you should edit your program and assemble it again if there any
syntax errors.
It is typical that the first executable version of your program to have some runtime errors. These
errors are not detected by the assembler but occur when you are running your program. For
example, your program might compute erroneous results. Therefore, you should debug your
program to identify the errors at runtime. You can run your program with various inputs and under
different conditions to verify that it is working correctly. You can use the slow execution mode in
All MIPS instructions are 32-bit wide and occupy 4 bytes in memory. The address of a MIPS
instruction in memory is always a multiple of 4 bytes. There are three basic MIPS instruction
formats: Register (R-Type) format, Immediate (I-Type) format, and Jump (or J-Type) format as
shown in Figure 2.3.
All instructions have a 6-bit opcode that defines the format and sometimes the operation of an
instruction. The R-type format has two source register fields: Rs and Rt, and one destination
register field Rd. All register fields are 5-bit long and address 32 general-purpose registers. The sa
field is used as the shift amount for shift instructions and the funct field defines the ALU function
for R-type instructions.
The I-type format has two register fields only: Rs and Rt, where Rs is always a source register,
while Rt can be a destination register or a second source depending on the opcode. The 16-bit
The J-type format has no register field. The 26-bit Immediate field is used as an address in jump
and function call instructions.
R-Type Format
Op6 Rs5 Rt5 Rd5 sa5 funct6
I-Type Format
Op6 Rs5 Rt5 Immediate16
J-Type Format
Op6 Immediate26
The MIPS architecture defines 32 general-purpose registers, numbered from $0 to $31. The $ sign
is used to refer to a register. To simplify software development, the assembler can also refer to
registers by name as shown in Table 2.1. The assembler converts a register name to its
corresponding number.
The label is optional. It marks the memory address of the instruction. It must have a colon. In
addition, a label can be used for referring to the address of a variable in memory.
The operands specify the data required by the instruction. Different instructions have different
number of operands. Operands can be registers, memory variables, or constants. Most arithmetic
and logical instructions have three operands.
An example of a MIPS instruction is shown below. This example uses the addiu to increment the
$t0 register:
To be able to write programs, a basic set of instructions is needed. Only few instructions are described
in the following tables. Table 2.2 lists the basic arithmetic instructions and Table 2.3 lists basic
control instructions.
Instruction Meaning
add Rd, Rs, Rt Rd = Rs + Rt. Overflow causes an exception.
sub Rd, Rs, Rt Rd = Rs – Rt. Overflow causes an exception.
addi Rt, Rs, Imm Rt = Rs + Imm (16-bit constant). Overflow causes an exception.
li Rt, Imm Rt = Imm (pseudo-instruction).
la Rt, var Rt = address of var (pseudo-instruction).
move Rd, Rs Rd = Rs (pseudo-instruction).
Instruction Meaning
beq Rs, Rt, label if (Rs == Rt) branch to label.
bne Rs, Rt, label if (Rs != Rt) branch to label.
j label Jump to label.
System calls are operating-system specific. Each operating system provides its own set of system
calls. Because MARS is a simulator, there is no operating system involved. The MARS simulator
handles the syscall exception and provides system services to programs. Table 2.1 shows a small
set of services provided by MARS for doing basic I/O.
Before using the syscall instruction, you should load the service number into register $v0, and load
the arguments, if any, into registers $a0, $a1, etc. After issuing the syscall instruction, you should
retrieve return values, if any, from register $v0.
Now, we are ready to write a MIPS assembly language program. A simple program that asks the user
to enter an integer value and then displays the value of this integer is shown in Figure 2.4.
Five system calls are used. The first system call prints string str1. The second system call reads an
input integer. The third system call prints str2. The fourth system call prints the integer value that was
input by the user. The fifth system call exits the program.
1. Modify the program shown in Figure 2.4. Ask the user to enter an integer value, and then print
the result of doubling that number. Use the add instruction.
2. Modify again the program shown in Figure 2.4. Ask the user whether he wants to repeat the
program: "\nRepeat [y/n]? ". Use service code 12 to read a character and the branch
instruction to repeat the main function if the user input is character 'y'.
3. Write a MIPS program that asks the user to input his name and then prints "Hello ", followed
by the name entered by the user.
4. Write a MIPS program that executes the statement: s = (a + b) – (c + 101), where a, b, and c are
user provided integer inputs, and s is computed and printed as an output. Answer the following:
a. Suppose the user enters a = 5, b = 10, and c = -30, what is the expected value of s?
b. Which instruction in your program computed the value of s and which register is used?
c. What is the address of this instruction in memory?
d. Put a breakpoint at this instruction and write the value of the register used for computing s in
decimal and hexadecimal.
5. Write a MIPS program that inputs two integer values. The program should output equal if the
two integers are equal. Otherwise, it should output not equal. Use the branch instruction to
check for equality.