0% found this document useful (0 votes)
43 views

CS 330 - Lab 6

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views

CS 330 - Lab 6

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

CS 330 Hardware and Systems Fundamentals

Spring 2024 – Lab # 6: Introduction to MIPS Assembly

Language using MARS Simulator

Due Date: Sunday, 3rd March 2024

Introduction to MARS
Welcome to MIPS Assembly Language! We will introduce the MARS Simulator interface and
its basic navigation features, interact with the various registers in MIPS, write a simple "Hello
Assembly" program, print integers, characters, and floats, and perform basic arithmetic
operations.

Lab objectives

1. Introduction to MARS Simulator Interface:


o Familiarize students with the MARS simulator interface, including the text
editor, console output, register window, and memory viewer.
o Explain the purpose and functionality of each component to ensure students
understand how to navigate the simulator.
2. Basic MIPS Instructions:
o Introduce students to fundamental MIPS assembly instructions such as add, sub,
lw, sw, beq, jal, etc.
o Demonstrate the syntax and usage of each instruction, emphasizing their role in
manipulating data and controlling program flow.
3. Data Declaration and Memory Management:

Page 1 of 17
o
Teach students how to declare data in the .data section using directives like .word,
.ascii, and .asciiz.
o Explain memory management concepts such as byte addressing and memory
alignment.
o Guide students on how to access and manipulate data stored in memory using
load and store instructions.
4. Debugging and Testing Techniques:
o Teach students how to debug MIPS assembly programs using the MARS
simulator's debugging features.
o Introduce techniques such as setting breakpoints, stepping through code,
inspecting register and memory contents, and tracking program flow.
o Encourage students to identify and troubleshoot common errors such as syntax
errors, logical errors, and runtime errors.

Materials:

• MIPS Mars Simulator Software


• Handout with instructions and diagrams

After completing this lab, you will:

• Get familiar with the MARS simulator.


• Learn how to assemble, run, and debug a MIPS program.

MARS, the MIPS Assembly and Runtime Simulator, is an integrated development


environment (IDE) for programming in the MIPS assembly language. It allows editing,
assembling, debugging and simulating the execution of MIPS assembly language programs.
MARS is written in Java.
There are two main windows in MARS, as shown in Figure 1.1.
• The Edit window: used to create and modify a MIPS program.

• The Execute window: used to run and debug a MIPS program.

To switch between the Edit and the Execute windows, use the tabs at the top.
The Execute window contains three main panes:
1. Text Segment: shows the machine code and related addresses.
2. Data Segment: shows memory locations that hold variables in the data segment.
3. Labels: shows addresses of labeled items, i.e. variables and jump endpoints.

There are two tabbed message areas at the bottom of Figure 1.1:

Page 2 of 17
1. The Mars Messages tab: Used for messages such as assembly or runtime errors and
informational messages. You can click on assembly error messages to select the
corresponding line of code in the editor.
2. The Run I/O tab: Used at runtime for displaying console output and entering console
input as program execution progresses.

Figure 1.1: The MARS Integrated Development Environment (IDE)

Figure 1.2 shows the MARS Execute window’s panes, and emphasizes the following features:
1. The Execute window’s tab.

2. Assembly code displayed with addresses and machine code.

3. Values stored in the data segment. These are directly editable.

4. Controls for navigating the data memory area. Allows switching to view the stack
segment.

5. Switching between decimal and hexadecimal addresses and values in memory and
registers.

6. Labels and their corresponding memory addresses.

Page 3 of 17
7. Values stored in registers. These are directly editable.

8. Checkboxes used to setup breakpoints for each MIPS instruction. Useful in debugging.

9. Execution speed selection. Useful in debugging.

Figure 1.2: The MARS Execute Window

At all times, the MIPS register window appears on the right-hand side of the screen,
even when you are editing and not running a program. While writing a program, this
serves as a useful reference for register names and their use. Move the mouse over the
register name to see the tool tips.
There are three register tabs:

The Register File: integer registers $0 through $31, HI, LO, and the Program Counter PC.
Coprocessor 0: exceptions, interrupts, and status codes.
Coprocessor 1: floating point registers.

Assemble, Run, and Debug a MIPS Program


To assemble the file currently in the Edit tab, select Assemble from the Run menu, or use the
Assemble toolbar icon.
If there are syntax errors in the program, they will appear in the Mars Messages tab at the
bottom of the MARS screen. Each error message contains the line and column where the
error occurred.
Once a MIPS program assembles successfully, the registers are initialized, and the Text
Segment and the Data Segment are filled, as shown in Figure 1.3.

Page 4 of 17
Figure 1.3: MARS screen after running the Assemble command.

After running the Assemble command, you can now execute the program. The Run menu and
the toolbar contain the following execution options:
Menu Item Icon Action

Run > Assemble Assemble the program.

Run > Go Run the program to completion, or until the next breakpoint.

Reset the program and simulator to initial values. Allows


Run > Reset
restarting program execution.

Single-step execution: execute one instruction at a time. Allows


Run > Step debugging the program by inspecting register and memory after
executing each single instruction.

Run > Backstep Single-step backwards: “unexecute” the last executed instruction.

Page 5 of 17
The Run Speed Slider allows running the program at full speed or
slowing it down so you can watch the execution. Affects normal
execution only, not single-step execution.

You can set a breakpoint at any instruction by checking the checkbox in front of the instruction
in the text segment pane.
During execution, the instruction being executed is highlighted in yellow, and the register
that was last modified is highlighted in green. Also, the variable that was last updated in the
data segment is highlighted in blue. It’s usually only possible to see the highlighting when
you are stepping or running at less than full speed.
For more details about the MARS simulator, refer to the MARS documentation at the
following link: http://courses.missouristate.edu/KenVollmar/MARS/

Part 1 - Introduction:
• Every MIPS Program has two sections. These include the text and data
sections.

MIPS Data Types: https://www.assemblylanguagetuts.com/mips-assembly-data-types/

MIPS SYSCALL Functions:


https://courses.missouristate.edu/kenvollmar/mars/help/SyscallHelp.html

Part 2 - Registers:
Registers are the fastest memory in our computers. Registers are like variables. However,
unlike variables which store data in the main memory, registers store data in the processor itself
(exciting right!). Although Assembly language may seem complex, it gives you more control
and power over the registers as compared to high-level programming languages.
Registers Functions
$zero Constant for 0. Always 0
$at Reserved for assembler
$v0 - $v1 Expression evaluation and function results
$a0 - $a3 Stores arguments

Page 6 of 17
$t0 - $t9 Temporaries, not saved
$s0 - $s7 Contents saved for later use
$k0 - $k1 Reserved for OS kernel
$gp Global Pointer
$sp Stack Pointer
$fp Frame pointer
$ra Return Address

Download the file titled print_values.asm on Canvas.

Part 3 – Printing a String: Hello Assembly!


Remember, every MIPS Program has two sections. These include the text and data sections.

We must define the variables (in memory) to contain our string in the data section. Remember
that the computer understands only numbers, hence we need a system to represent strings with
numbers – ASCII.

In MIPS, strings are normally null-terminated as in C. Therefore, using .asciiz instead of ASCII
stores the specified string in the NULL-terminated format.

In the data section, declare a variable named firstMessage and store the null-terminated string
“Hello Assembly \n”.

What we are left with is to print the string right? We now need to perform a SYSCALL – the
interface between our program and the O.S kernel that allows us to perform services like print
strings, get user input or open files. Therefore, the syscall transfers control to the operating
system to perform a requested service.

Page 7 of 17
We need to tell the system what service to perform. Every syscall has a service number (See
https://courses.missouristate.edu/kenvollmar/mars/help/SyscallHelp.html for a list of
available syscall services).

How to use SYSCALL system services

i. Step 1: Load the service number in register $v0.


ii. Step 2: Load argument values, if any, in $a0, $a1, $a2 or $f12 as specified.
iii. Step 3: Issue the SYSCALL function.
iv. Step 4: Retrieve return values, if any, from result registers as specified.

Printing a string is service number 4. Our complete code for printing the string is:

Part 4 – Printing a Character


Create a new file and name as print_character.asm. The process is similar to the printing of
a string. We can use the same syscall service (i.e., we can treat a character like a string),
however, the data type used to represent a character is a byte.

Part 5 – Printing an Integer


Create a new file and name as print_integer.asm. The process is similar to the ones above,
however:
• The data type for an integer in MIPS is a word.
• The syscall service number is 1.
• In this case, the loading argument value will be achieved using lw – load word.

Page 8 of 17
Part 6 – Printing a Float (Single-precision floating points: 32 bits)
Create a new file and name as print_float.asm. Again, the process is similar, however:
• The data type for a float is float.
• The syscall service number is 2.
• The value is loaded into argument register $f12 in the coprocessor1 using l.s – for
loading single-precision floating numbers. You can also use lwc1 – load word
coprocessor1. Remember, the coproc1 has the registers for single-precision floating
points.

Part 7 – Printing a Double (Double-precision floating points: 64


bits)
A double consists of 64 bits; therefore, two floating-point registers will be required. For
instance, if a double is stored in the register $f0, half of the bits will be stored in $f1 (doubles
require 64 bits). Therefore, doubles are only stored in the registers with even number identifiers
e.g., $f0, $f2, $f4…
Again, the process is similar, however:
• The data type for double is double.
• The syscall number for printing a double is 3.
• The value is loaded into argument register $f12 (same for single-precision floats) in
the coprocessor 1 using l.d – load double-precision float or ldc1 – load double
copressor1.

Page 9 of 17
Part 8 – Printing string together with an integer, float, or double.
Congratulations! We can now print strings, characters, integers, floats and doubles! Let us print
a message that describes an integer, e.g., describing our mid-semester exam score.

Part 9 – Integer Arithmetic


In this section, we will learn how to perform arithmetic operations on integers. Remember, all
arithmetic operations in MIPS have a similar format.

Page 10 of 17
Let us try something interesting! Instead of declaring variables in memory, let us only use
registers for our program, which means that we will initialize our values to multiply directly
with registers and not load from memory.

NB: n-bit * n-bit = (n+n)-bit product size. For e.g, multiplying two 16-bit numbers results in a
32-bit product.

Using mul:
The mul operation allows us to multiply integers of 16-bit sizes. The product of 2 two 16-bit
integers will result in a 32-bit product size. Therefore, we can only use mul for operations
whose products are not more than 32 bits.

Using sll:
Shift Left Logical allows us to perform multiplication efficiently.
For instance, sll $t0, i = $t0 * 2 raise to the power i.

Page 11 of 17
Like multiplication, there are several ways of performing the division operation. The simplest
and most common is similar to the add, sub, and mul operations.

Using div:

You can also use the div operation in various forms when you hover your cursor on the div
keyword. Let us see an interesting one here – we want to be able to display the quotient and
remainder, if any. Here, div takes only two registers (the numbers involved in the division
operation). The quotient is stored in the lo register, while the remainder is stored in the hi
register.

Using srl:
Shift Right Logical allows us to perform division efficiently.
For instance, srl $t0, i = $t0 / 2 raised to the power i.

Page 12 of 17
NB: Unfortunately, MIPS does not support immediate floating-point arithmetic instructions,
so we must load values into a floating-point register first.

Part 10 – Single-Precision Floating Point Arithmetic


The processes are similar to integer arithmetic. Create a new file called float_arithmetic.asm.
For addition, the operation command is add.s – add single-precision float.
Remember the syscall for printing float is 2.

Part 11 – Double-Precision Floating-Point Arithmetic


The processes are similar to float arithmetic. Create a new file called double_arithmetic.asm.
For addition, the operation command is add.d – add double-precision float.
Remember, the syscall for printing float is 3.

Page 13 of 17
Part 12: Getting inputs from the user.
The syscall service number for reading an integer is 5, a float is 6, a double is 7 and a string is
8.
Let us create a simple program to ask the user to input their age (integer) and display a message
showing their age on the screen. Name as readInt.asm

Part 13: Control Flow Statements:

Let us look at how to use the conditional if statement in MIPS to compare two values.

Page 14 of 17
How can we write the same program using bne?

Part 14: Set-on-Less-Than


Here we can use the common cases (beq, bne) in combination with the slt command to achieve
blt, bgt etc. Slt command helps us to compare two values. If the first is less than the other. It
evaluates to 1 if the condition is true, and 0 otherwise. Once we know the result from the slt
command, we can use our branch instructions to continue the execution of our program.

Page 15 of 17
Part 15: Post-Lab Deliverable

Task 1: Write an assembly program that prompts the user to enter three integers, and then
checks if the first integer is equal to the sum of the second and third integers. If it is, print "The
first number is equal to the sum of the second and third numbers"; otherwise, print "The first
number is not equal to the sum of the second and third numbers".

Task 2: Write an assembly program that prompts the user to enter four integers, and then
checks if the difference of the first two is equal to the difference of the last two. If it is, print
"The differences are equal"; otherwise, print "The differences are not equal".

Part 16: Reflection Questions


1. What are the advantages and disadvantages of using assembly language compared to
high-level programming languages?
2. How does the MIPS architecture influence the design of assembly language programs?

Page 16 of 17
3. What are some common pitfalls and challenges encountered when programming in the
MIPS assembly language?
4. How does the MARS simulator aid in learning and debugging MIPS assembly language
programs?

Submission:
Submit a zip file that contains:
• Task 1 and 2 codes in Part 15
• PDF of written responses to the reflection questions.
Name the zip file ID_Lab6.

Page 17 of 17

You might also like