Building Your First Simple Program With The MIPS Assembly Language

155544 VIEWS

· ·

MIPS assembly language simply refers to the assembly language of the MIPS processor. The term MIPS is an acronym for Microprocessor without Interlocked Pipeline Stages. It is a reduced-instruction set architecture developed by an organization called MIPS Technologies.

The MIPS assembly language is a very useful language to learn because many embedded systems run on the MIPS processor. Knowing how to code in this language brings a deeper understanding of how these systems operate on a lower level.

Before you start coding in the MIPS assembly language

Before you start churning out MIPS assembly language code, you need to first obtain a very good Integrated Development Environment.  That can help to compile and execute your MIPS assembly language code. The software that I would recommend this purpose is the MARS (MIPS Assembler and Runtime Simulator). You can find it easily on Google, and download it.

Introduction to the MIPS architecture

Data Types

  1. All the instructions in MIPS are 32 bits.
  2. A byte in the MIPS architecture represents 8 bits; a halfword represents 2 bytes (16 bits) and a word represents 4 bytes (32 bits).
  3. Each character used in the MIPS architecture requires 1 byte of storage. Each integer used requires 4 bytes of storage.

Literals
In the MIPS architecture, literals represent all numbers (e.g. 5), characters enclosed in single quotes (e.g. ‘g’) and strings enclosed in double quotes (e.g. “Deadpool”).

Registers
MIPS architecture uses 32 general-purpose registers. Each register in this architecture is preceded by ‘$’ in the assembly language instruction. You can address these registers in one of two ways. Either use the register’s number (that is, from $0 to $31), or the register’s name (for example, $t1).

General structure of a program created using the MIPS assembly language

A typical program created using the MIPS assembly language has two main parts. They are the data declaration section of the program and the code section of the program.

Data declaration section of a MIPS assembly language program

The data declaration section of the program is the part of the program identified with the assembler directive .data. This is the part of the program in which all the variables to be used in the program are created and defined. It is also the part of the program where storage is allocated in the main memory (RAM).

The MIPS assembly language program declares variables as follows:

 name:          	.storage_type          	value(s)

The “name” refers to the name of the variable being created. The “storage_type” refers to the type of data that the variable is meant to store. The “value(s)” refers to the information to be stored in the variable being created. The following MIPS assembly language syntax creates a single integer variable with the initial value of 5:

 .data
    var1:   	 .word   	 5

Code section of the MIPS assembly language program

The code section of the program is the part of the program in which the instructions to be executed by the program are written. It is placed in the section of the program identified with the assembler directive .text. The starting point for the code section of the program is marked with the label “main” and the ending point for the code section of the program is marked with an exit system call. This section of a MIPS assembly language program typically involves the manipulation of registers and the performance of arithmetic operations.

Manipulation of registers

In the manipulation of registers, the MIPS assembly language utilizes the concepts of load, and indirect or indexed addressing.

In the concept of load addressing, the Random-Access Memory address of a variable in the MIPS assembly language program is copied and stored in a temporary register. For instance, to copy the address of a variable called “var1” into the temporary register $t0, the following MIPS assembly language syntax is required:

 la $t0, var1

In the concept of indirect addressing, the value stored in a particular Random-Access Memory address is copied into a temporary register. For example, use the following MIPS assembly language syntax to copy an integer value stored in the Random-Access Memory address of register $t0 into register $t2

 lw $t2, ($t0)

In the concept of indexed addressing, the Random-Access Memory address of a register can be offset by a specified value to obtain a value stored in another Random-Access Memory address. For instance, to obtain the value stored in a Random-Access Memory address which is four addresses away from the Random-Access Memory address of the register $t0, and store that value in register $t2, the following MIPS assembly language syntax is required:
lw $t2, 4($t0)

Performance of arithmetic operations

In the MIPS assembly language, most arithmetic operations use three operands, and all these operands are registers. The size of each operand is a word, and the general format for performing arithmetic operations in the MIPS assembly language is shown as follows:

 arithmetic_operation storage_register, first_operand, second_operand

Where “arithmetic_operation” refers to the arithmetic operation that is being performed, “storage_register” refers to the register that is used to store the result of the arithmetic computation; “first_operand” refers to the register that contains the first operand of the arithmetic operation, and “second_operand” refers to the register that contains the second operand of the arithmetic operation.

The most common arithmetic operations implemented in the MIPS assembly language are addition, subtraction, multiplication and division. The following table represents the various arithmetic operations that have been listed and how they are represented in the MIPS assembly language:

Creating a simple MIPS assembly language program

In this post, we create a simple program that can obtain two different numbers from a user and perform the arithmetic operations of addition, subtraction and multiplication on those two numbers.

The first thing to do when creating this program is to define the variables that are to be used to store the strings used in the program.

#This is a simple program to take two numbers from the user and perform
#basic arithmetic functions such as addition, subtraction and multiplication with them

#Program flow:
#1. Print statements to ask the user to enter the two different numbers
#2. Store the two numbers in different registers and print the ‘menu’ of arithmetic instructions to the user
#3. Based on the choice made by the user, create branch structures to perform the commands and print the result
#4. Exit the program

 .data    
    prompt1:    .asciiz   	 "Enter the first number: "
    prompt2:    .asciiz   	 "Enter the second number: "
    menu:   	 .asciiz   	 "Enter the number associated with the operation you want performed: 1 => add, 2 => subtract or 3 => multiply: "
    resultText:    .asciiz   	 "Your final result is: "

The second thing to do is to pre-load the integer values representing the various instructions to be performed by the program into their respective registers for storage.

 .text
.globl main
main:
    #The following block of code is to pre-load the integer values representing the various instructions into registers for storage
    li $t3, 1    #This is to load the immediate value of 1 into the temporary register $t3
    li $t4, 2    #This is to load the immediate value of 2 into the temporary register $t4
    li $t5, 3    #This is to load the immediate value of 3 into the temporary register $t5

Then, print out the instructions that require the user to input the two numbers that they would like to perform the arithmetic operations on.

 #asking the user to provide the first number
    li $v0, 4     #command for printing a string
    la $a0, prompt1 #loading the string to print into the argument to enable printing
    syscall   	 #executing the command
    

    
    #the next block of code is for reading the first number provided by the user
    li $v0, 5    #command for reading an integer
    syscall   	 #executing the command for reading an integer
    move $t0, $v0     #moving the number read from the user input into the temporary register $t0
    
    #asking the user to provide the second number
    li $v0, 4    #command for printing a string
    la $a0, prompt2    #loading the string into the argument to enable printing
    syscall   	 #executing the command
    
    
    #reading the second number to be provided to the user
    li $v0, 5    #command to read the number  provided by the user
    syscall   	 #executing the command for reading an integer
    move $t1, $v0    #moving the number read from the user input into the temporary register $t1

The next step is to print out the commands the user can perform on the two numbers that have been provided. This is to enable the user to select a course of action.

#the next block of code is to print all of the commands that the user can take with regards to the #two numbers that he or she has provided

 li $v0, 4    #command for printing a string
    la $a0, menu    #loading the string into the argument to enable printing
    syscall   	 #executing the command
    


    #the next block of code is to read the number provided by the user
    li $v0, 5    #command for reading an integer
    syscall   	 #executing the command
    move $t2, $v0    #this command is to move the integer provided into the temporary register $t2

At this point, you need to create control structures that determine which instructions are to be executed based on the command issued by the user.

The following lines of code determine what should take place depending on the integer value # that was provided by the user

 beq $t2,$t3,addProcess    #Branch to 'addProcess' if $t2 = $t3
    beq $t2,$t4,subtractProcess #Branch to 'subtractProcess' if $t2 = $t4
    beq $t2,$t5,multiplyProcess #Branch to 'multiplyProcess' if $t2 = $t5

The next code instructs adding the two numbers provided.

 addProcess:
    add $t6,$t0,$t1    #this adds the values stored in $t0 and $t1 and assigns them to the     temporary register $t6
    
    #The following line of code is to print the results of the computation above
    li $v0,4    #this is the command for printing a string
    la $a0,resultText    #this loads the string to print into the argument $a0 for printing
    syscall   	 #executes the command
    
    #the following line of code prints out the result of the addition computation
    li $v0,1
    la $a0, ($t6)
    syscall
    
    li $v0,10 #This is to terminate the program

This is an example of code for instructions to subtract the two numbers provided.

 subtractProcess:
    sub $t6,$t0,$t1 #this adds the values stored in $t0 and $t1 and assigns them to the temporary register $t6
    li $v0,4    #this is the command for printing a string
    la $a0,resultText    #this loads the string to print into the argument $a0 for printing
    syscall   	 #executes the command
    
    #the following line of code prints out the result of the addition computation
    li $v0,1
    la $a0, ($t6)
    syscall
    
    li $v0,10 #This is to terminate the program

This code is for instructions to multiply the two numbers provided.

 multiplyProcess:
    mul $t6,$t0,$t1 #this adds the values stored in $t0 and $t1 and assigns them to the temporary register $t6
    li $v0,4    #this is the command for printing a string
    la $a0,resultText    #this loads the string to print into the argument $a0 for printing
    syscall   	 #executes the command
    
    #the following line of code prints out the result of the addition computation
    li $v0,1
    la $a0, ($t6)
    syscall
    
    li $v0,10 #This is to terminate the program

When you are done implementing the code shown above, just compile your program and run it. Congratulations! You have implemented your first MIPS assembly language program. 😊

Additional references to learn more about MIPS assembly language syntax:
https://chortle.ccsu.edu/AssemblyTutorial/index.html

Conclusion

:
I hope that in this tutorial you have received all the basic skills you need to help you to create a very simple MIPS assembly language program.


David Sasu is a senior studying Computer Science in Ashesi University. He is passionate about understanding technology and using it to solve important problems. He is currently working on the creation of information systems for under-funded orphanages in his country, Ghana. He hopes to specialize in the fields of Artificial Intelligence and cybersecurity to enable him to create systems to help safeguard and improve the African continent.


Discussion

Click on a tab to select how you'd like to leave your comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Menu
Skip to toolbar