MIPS Architecture and Assembly Language


Architecture Overview

Data Types and Literals

Data types:

Literals:

Registers


MIPS Assembly Language Program Structure

Data Declarations

Code

Comments

ex:		A template for a MIPS assembly language program


# Comment giving name of program and description of function
# Template.s
# Bare-bones outline of MIPS assembly language program


.data
# variable declarations here
# ...


.text

main: # indicates start of code (first instruction to execute)
# remainder of program code here
# ...
# ...


Data Declarations

format for declarations:

name:	storage_type	value(s)	
Note: labels always followed by colon ( : )

example

var1: .word 3 # create a single integer variable with initial value 3
array1: .byte 'a','b' # create a 2-element character array with elements initialized
# to a and b
array2: .space 40 # allocate 40 consecutive bytes, with storage uninitialized
# could be used as a 40-element character array, or a
# 10-element integer array; a comment should indicate which!


Instructions

Load / Store Instructions

load:

store word: load immediate:

example

.data
var1: .word 23 # declare storage for var1; initial value is 23

.text
__start:
lw $t0, var1 # load contents of RAM location into register $t0: $t0 = var1
li $t1, 5 # $t1 = 5 ("load immediate")
sw $t1, var1 # store contents of register $t1 into RAM: var1 = $t1
done


Indirect and Based Addressing

load address:

indirect addressing:

based or indexed addressing:

example

.data
array1: .space 12 # declare 12 bytes of storage to hold array of 3 integers

.text
__start: la $t0, array1 # load base address of array into register $t0
li $t1, 5 # $t1 = 5 ("load immediate")
sw $t1, ($t0) # first array element set to 5; indirect addressing
li $t1, 13 # $t1 = 13
sw $t1, 4($t0) # second array element set to 13
li $t1, -7 # $t1 = -7
sw $t1, 8($t0) # third array element set to -7
done


Arithmetic Instructions

		add	$t0,$t1,$t2	#  $t0 = $t1 + $t2;   add as signed (2's complement) integers
sub $t2,$t3,$t4 # $t2 = $t3 Ð $t4
addi $t2,$t3, 5 # $t2 = $t3 + 5; "add immediate" (no sub immediate)
addu $t1,$t6,$t7 # $t1 = $t6 + $t7; add as unsigned integers
subu $t1,$t6,$t7 # $t1 = $t6 + $t7; subtract as unsigned integers

mult $t3,$t4 # multiply 32-bit quantities in $t3 and $t4, and store 64-bit
# result in special registers Lo and Hi: (Hi,Lo) = $t3 * $t4
div $t5,$t6 # Lo = $t5 / $t6 (integer quotient)
# Hi = $t5 mod $t6 (remainder)
mfhi $t0 # move quantity in special register Hi to $t0: $t0 = Hi
mflo $t1 # move quantity in special register Lo to $t1: $t1 = Lo
# used to get at result of product or quotient

move $t2,$t3 # $t2 = $t3


Control Structures

Branches

		b	target			#  unconditional branch to program label target
beq $t0,$t1,target # branch to target if $t0 = $t1
blt $t0,$t1,target # branch to target if $t0 < $t1
ble $t0,$t1,target # branch to target if $t0 <= $t1
bgt $t0,$t1,target # branch to target if $t0 > $t1
bge $t0,$t1,target # branch to target if $t0 >= $t1
bne $t0,$t1,target # branch to target if $t0 <> $t1

Jumps

		j	target		#  unconditional jump to program label target
jr $t3 # jump to address contained in $t3 ("jump register")

Subroutine Calls

subroutine call: "jump and link" instruction

	jal	sub_label	#  "jump and link"
subroutine return: "jump register" instruction
	jr	$ra	#  "jump register"

Note: return address stored in register $ra; if subroutine will call other subroutines, or is recursive, return address should be copied from $ra onto stack to preserve it, since jal always places return address in this register and hence will overwrite previous value


System Calls and I/O (SPIM Simulator)

ex   Print out integer value contained in register $t2
		li	$v0, 1		# load appropriate system call code into register $v0;
					# code for printing integer is 1
		move	$a0, $t2	# move integer to be printed into $a0:  $a0 = $t2
		syscall			# call operating system to perform operation

ex   Read integer value, store in RAM location with label int_value (presumably declared in data section)
		li	$v0, 5		# load appropriate system call code into register $v0;
					# code for reading integer is 5
		syscall			# call operating system to perform operation
		sw	$v0, int_value	# value read from keyboard returned in register $v0;
					# store this in desired location

ex   Print out string (useful for prompts)

		.data
string1		.asciiz	"Print this.\n"	# declaration for string variable

		.text
main:		li	$v0, 4		# load appropriate system call code into register $v0;
					# code for printing string is 4
		la	$a0, string1	# load address of string to be printed into $a0
		syscall			# call operating system to perform print operation
	


Note:

Note: To indicate end of program, use exit system call; thus last lines of program should be:

		li	$v0, 10		# system call code for exit = 10
syscall # call operating system

Table of System Call Codes and Arguments
(from SPIM S20: A MIPS R2000 Simulator, James J. Larus, University of Wisconsin-Madison)

Service System Call Code Arguments Result
print integer 1 $a0 = value (none)
print float 2 $f12 = float value (none)
print double 3 $f12 = double value (none)
print string 4 $a0 = address of string (none)
read integer 5 (none) $v0 = value read
read float 6 (none) $f0 = value read
read double 7 (none) $f0 = value read
read string 8 $a0 = address where string to be stored
$a1 = number of characters to read + 1
(none)
memory allocation 9 $a0 = number of bytes of storage desired $v0 = address of block
exit (end of program) 10 (none) (none)


Examples


Example 1

# Compute the value of the sum     1*2 + 2*3 + 3*4 + ... + 10*11,   and store in register $t1

.data # variable declaration section

out_string: .asciiz "The result is:\n" # declares a null-terminated string, to "prettify" output

.text

main: # indicates start of code
li $t0, 1 # $t0 will be a counter; initialize to 1
li $t1, 0 # $t1 will hold the sum
li $t2, 10 # $t2 will hold loop limit

loop_top: bgt $t0,$t2,loop_end # exit loop if $t0 > 10
addi $t3,$t0,1 # $t3 = $t0 + 1
mult $t0,$t3 # special register Lo = $t0 * $t3
# (don't need Hi since values are small)
mflo $t3 # $t3 = Lo (= $t0 * $t3)
add $t1,$t1,$t3 # $t1 = $t1 + $t3
addi $t0, 1 # increment counter
b loop_top # branch to loop_top

loop_end: # print out the result string
li $v0, 4 # system call code for printing string = 4
la $a0, out_string # load address of string to be printed into $a0
syscall # call operating system to perform print operation

# print out integer value in $t1
li $v0, 1 # system call code for printing integer = 1
move $a0, $t1 # move integer to be printed into $a0: $a0 = $t1
syscall # call operating system to perform print

# exit program
li $v0, 10 # system call code for exit = 10
syscall # call operating system

# blank line at end to keep SPIM happy!


Example 2

# Code with subroutine to compute Fibonacci number recursively
# Uses system stack


.data
in_string: .asciiz "Input a positive integer:\n\n"
out_string: .asciiz "The Fibonacci number is:\n\n"


.text
main:
# print out prompt
li $v0, 4 # system call code for printing string = 4
la $a0, in_string # load address of string to be printed into $a0
syscall # call operating system to perform print operation

# read integer into $s0
li $v0, 5 # system call code for read integer = 5
syscall # call operating system
move $s0, $v0 # value read from keyboard returned in register $v0; transfer to $s0

sw $s0,($sp) # push argument for Fib on stack
addi $sp,$sp,-4 # and decrement stack pointer
jal Fib # jump to subroutine
addi $sp,$sp,4 # increment stack pointer
lw $s1,($sp) # and pop result from stack

# print out prompt
li $v0, 4 # system call code for printing string = 4
la $a0, in_string # load address of string to be printed into $a0
syscall # call operating system

# print out result (stored in $s1)
li $v0, 1 # system call code for printing integer = 1
move $a0, $s1 # move integer to be printed into $a0: $a0 = $s1
syscall # call operating system to perform print

# exit program
li $v0, 10 # system call code for exit = 10
syscall # call operating system

# blank line at end to keep SPIM happy!


##################################################################################
# Fibonacci subroutine
# input: integer n, on stack
# output: Fib(n), nth Fibonacci number
# description: recursively computes Fib(n) = Fib(n-1) + Fib(n-2), Fib(1) = Fib(2) = 1.
# uses: $t0, $t1
##################################################################################


Fib:
# procedure prologue:
sw $ra,($sp) # save return address on stack, since recursive,
addi $sp,$sp,-4 # and decrement stack pointer
sw $fp,($sp) # save previous frame pointer on stack
addi $sp,$sp,-4 # and decrement stack pointer
add $fp,$sp,12 # set frame pointer to point at base of stack frame

lw $t0,($fp) # copy argument to $t0: $t0 = n
li $t1, 2
bgt $t0,$t1,do_recurse # if argument n >= 2, branch to recursive sequence
li $t0, 1 # else set result to 1 (base cases n = 1 and n = 2)
b epilogue # branch to end

do_recurse: addi $t0,$t0,-1 # $t0 = n-1
sw $t0,($sp) # push argument n-1 on stack
addi $sp,$sp,-4 # and decrement stack pointer
jal Fib # call Fibonacci with argument n-1
# leave result on stack for now
lw $t0,($fp) # re-copy argument to $t0: $t0 = n
addi $t0,$t0,-2 # $t0 = n-2
sw $t0,($sp) # push argument n-2 on stack
addi $sp,$sp,-4 # and decrement stack pointer
jal Fib # call Fibonacci with argument n-2
addi $sp,$sp,4 # increment stack pointer
lw $t0,($sp) # and pop result of Fib(n-2) from stack into $t0
addi $sp,$sp,4 # increment stack pointer
lw $t1,($sp) # and pop result of Fib(n-1) from stack into $t1
add $t0,$t0,$t1 # $t0 = Fib(n-2) + Fib(n-1); have result

epilogue: # procedure epilogue: $t0 holds result
addi $sp,$sp,4 # increment stack pointer
lw $fp,($sp) # and pop saved frame pointer into $fp
addi $sp,$sp,4 # increment stack pointer
lw $ra,($sp) # and pop return address into $ra
addi $sp,$sp,4 # increment stack pointer
# to pop argument (n) from stack (discard)
sw $t0,($sp) # push result onto stack
addi $sp,$sp,-4 # and decrement stack pointer
jr $ra # return to caller

##################################################################################
# end of Fibonacci
##################################################################################


Comments? To send e-mail, click on the link below:
jsevy@cs.drexel.edu