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 Flow Instructions

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)


Example


# 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!

Any concern about the goals, questions, or wording of this document, please send a message to Jorge Vasconcelos.
Return to the CSF Homepage