Data types:
Literals:
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 # ... # ...
format for declarations:
name: storage_type value(s)
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!
load:
lw register_destination, RAM_source
lb register_destination, RAM_source
sw register_source, RAM_destination
sb register_source, RAM_destination
li register_destination, value
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
load address:
la $t0, var1
indirect addressing:
lw $t2, ($t0)
sw $t2, ($t0)
based or indexed addressing:
lw $t2, 4($t0)
sw $t2, -12($t0)
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
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
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"
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
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 operationNote:
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) |
# 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!