Books and References © Rance Necaise
IntroductionChapter 3. MIPS Assembly LanguagePseudo Instructions

Integer Arithmetic

All computers must be able to perform integer arithmetic. The MIPS architecture is no different. In this section, we explore the operations for integer arithmetic. In machine code, the intructions for working with floating-point values are handled separately and use a different set of instructions. Those will be covered in a later chapter.

Instruction Format

Arithmetic instructions in MIPS all have the same format. They take three arguments, all of which must be registers

mathop rd, rs, rt

The first operand is the destination register, while the second and third are the two values used in the computation. Consider the add example from the previous section.

add $t0, $t1, $t2

which adds the values stored in registers $t1 and $t2 and stores the result in register $t0. This format corresponds to the natural ordering of mathematical operations in a high-level language

A = B + C

The design of the arithmetic instructions is derived from two basic principles: "simplicity favors regularity" and "smaller is faster". Since all of the arithmetic instructions were designed to perform a single operation, they can all have the same number of operands that are specified in the same order. This helps programmers remember how to write the instructions. By requiring all of the arithmetic operations to use registers, less circuitry is required to implement the instructions, which results in faster operations.

This simplicity can complicate things, however. Consider the following mathematical expression written in a high-level language

A = B + C + D

This single high-level language statement will require several MIPS instructions in order to evaluate the entire expression

add $t4, $t1, $t2 # t = B + C
add $t0, $t4, $t3 # A = t + D

The temporary value that results from adding B + C must be stored in a temporary register so it can be used in the next instruction.

Registers

Most of the instructions in MIPS require the use of one or more registers in order to perform its operation. A register is a special storage location that is built into and is part of the processor. The data in the registers can be accessed much faster than data in memory.

The MIPS architecture provides 32 general purpose registers that can be accessed directly by a user program. Each register can store a word or 32-bits. The registers each have a symbolic name for use in assembly language as well as a numeric code that is used in the actual machine code instructions. Some of the registers are restricted and have a special purpose while the use of others is based on convention. All of the registers will be covered as needed throughout the text. Some of the more commonly used registers are listed in Table 1.

Symbolic NamePurpose
$zerostores the immediate value of 0.
$t0 - $t9general purpose, for temporary values.
$s0 - $s7general purpose, saved between function calls.
$a0 - $apassing function arguments.
$v0 - $v1stores function return values.
Table 1. Some of the more commonly used registers.

Most of the registers are read/write in that they can be read from or written to. One special register, however, is read only. MIPS includes the $zero register as it allows for fast initialization of registers and data storage. The $t and $s registers are typically used for arithmetic and for storing temporary and intermediate values. The difference between the two sets of registers will be discussed later in Chapter 5.

Before a register can be used, it must contain a value. All registers have an initial value when the program begins execution. To store a specific value into a register, we use the load immediate instruction

li $t1, 25

which takes two arguments, a register into which the value is to be stored and the immediate value to be stored in the register. The immediate value can be any integer value specified in decimal, octal, or hexadecimal

li $t2, -6
li $t3, 0x7A

Signed Arithmetic

MIPS provides a number of arithmetic operations as shown in Table 2. All of these arithmetic operations perform computations on 32-bit signed values. Thus, they assume the value stored in a register is a two's complement number.

InstructionDescription
add rd, rs, rtperforms signed addition: rd ← rs + rt
sub rd, rs, rtperforms signed subtraction: rd ← rs + rt
mul rd, rs, rtperforms signed multiplication: rd ← rs * rt
div rd, rs, rtperforms signed division: rd ← rs / rt
rem rd, rs, rtperforms signed remainder: rd ← rs % rt
Table 2. Arithmetic operations for signed values.

Consider the following MIPS code segment

add $t4, $t2, $t3
sub $t0, $t1, $t4

which adds the values stored in registers $t2 and $t3 and then subtracts the value in register $t4 from that sum. It is equivalent to the Python statement

x = y + z - t

Below is a complete example program using various arithmetic operations

# example2.asm
# Illustrates the use of several arithmetic operations.

.text

main: li $t1, 27
li $t2, 32
li $t3, 6
li $t5, 2

add $t4, $t2, $t3
sub $t0, $t1, $t4
mul $t0, $t0, $t5
rem $t2, $t0, $t5

li $v0, 10
syscall
Question 1.

Convert the MIPS assembly program in example2.asm above to Python code. Use appropriate variables to store the values instead of registers.

This program can be translated into the following Python code

b = 27
c = 32
d = 6
z = 2

t = c + d
a = b - t
a = a * z
c = a % z
Question 2.

Given the following Python code segment, translate it into MIPS assembly language. Assume the value of the variables are stored in the registers $t0 ... $t5.

a = b + c
d = e + f - a
add $t0, $t1, $t2 # a = b + c
add $t7, $t5, $t6 # t = e + f
sub $t3, $t7, $t0 # d = t - a
Question 3.

Convert the following Python code segment to MIPS assembly.

x = u + (y - z) + (v - w)

Assuming variables u - z are stored in registers $s0 - $s5:

sub $t0, $s4, $s5 # t0 = y – z
sub $t1, $s1, $s2 # t1 = v – w
add $t2, $s0, $t0 # t2 = u + t0
add $s3, $t2, $t1 # x = t2 + t1

Remember, order of operations and the use of parentheses matters when evaluating a mathematical expression.

Question 4.

Convert the following Python code segment to MIPS assembly.

a = b * (d - e)
b = b - (c + f) / a

Assuming variables a - f are stored in registers $t0 - $t5:

sub $s0, $t3, $t4 # t = (d - e)
mul $t0, $t1, $s0 # a = b * t
add $s0, $t2, $t5 # t = c + f
div $s0, $s0, $t0 # t = t / a
sub $t1, $t1, $s0 # b = b - t

Immediate Values

Adding and subtracting small literal values in a high-level program is very common. It is one of the most common type of add operations performed due to the use of loops and array/list subscripting. For example, consider this Python loop

i = 1
sum = 0
while i <= 100 :
sum = sum + i
i = i + 1

or the statement accessing array elements

avg = values[i] + values[i+5]

Thus, MIPS provides a special add instruction that can be used with small immediate signed values. The addi instruction adds an immediate value to the contents of a register and stores the result into a second register

addi $t0, $t1, 5

It's syntax is specified as

addi rd, rs, imm

The instruction works with both negative and positive immediate values

addi $t2, $t2, -1

The inclusion of this instruction is based on the principle "make the common case fast." Adding and subtracting small literal values is very common in computer programming. Thus, by including this instruction, a program does not first have to load the immediate value into a register and then perform the add operation. Instead, it can be done by one instruction which will be twice as fast as having to perform both a load and add operation.

Question 5.

Convert the following Python expression to MIPS assembly language

x = (y + 4) - z
addi $t0, $s1, 4
sub $s0, $t0, $s2
Question 6.

Convert the following Python expression to MIPS assembly language

x = 2 * y + 4 * z
li $t0, 2
mul $s0, $t0, $s1
li $t0, 4
mul $t0, $t0, $s2
add $s0, $s0, $t0

It is important to note that MIPS only provides an add immediate operation that performs addition with an immediate value. There are no immediate operations for the other arithmetic operations.

Unsigned Arithmetic

MIPS also provides several arithmetic instructions for working with unsigned values (see Table 3).

InstructionDescription
addu rd, rs, rtperforms unsigned addition: rd ← rs + rt
addiu rd, rs, immperforms unsigned addition with an immediate: rd ← rs + imm
subu rd, rs, rtperforms unsigned subtraction: rd ← rs - rt
Table 3. Arithmetic operations for unsigned values.

In MIPS, the only difference between the signed and unsigned operations is whether an overflow signal is raised when an overflow occurs. The signed arithmetic instructions all raise the overflow signal, while these instructions do not.

IntroductionChapter 3. MIPS Assembly LanguagePseudo Instructions
Page last modified on September 12, 2021, at 02:45 PM