[label:] mnemonic [operands] [#comment]
Label: (optional)
Marks the address of a memory location, must have a colon;
Typically appears in data and text segments
L1: addiu $t0, $t0, 1 #increment $t0
# Sample Program Template # Filename: # Author: # Date: # Description: # Register Usage: ################# Data segment ##################### .data . . . ################# Code segment ##################### .text .globl main main: # main program entry . . . li $v0, 10 # Exit program syscall
Syntax:
[name:] directive initializer [, initializer] . . .
var1: .WORD 10
All initializers become binary data in memory
.BYTE # Stores values as 8-bit bytes
.HALF # Stores values as 16-bit values aligned on half-word boundary
.WORD # stores values as 32-bit values aligned on word boundary
.WORD w:n # Stores values 32-bit value w into n consecutive words
# aligned on a word boundary.
.FLOAT # Stores values as single-precision floating point
.DOUBLE # Stores values as double-precision floating point
.ASCII # Allocates a sequence of bytes for an ASCII string
.ASCIIZ # .ASCII directive but adds a NULL char at end of string
.SPACE n # Allocates space of n uninitialized bytes in the data segment
.ALIGN n # Aligns the next data definition on a 2n byte boundary
MIPS instructions and integers occupy 4 bytes (a word)
Alignment means the address is a multiple of the size; e.g., Word address should be a multiple of 4 (Least significant 2 bits of a word aligned address should be 00); Halfword address should be a multiple of 2
Example Symbol Table
.DATA
var1: .BYTE 1, 2,'Z'
str1: .ASCIIZ "My String\n"
var2: .WORD 0x12345678
.ALIGN 3
var3: .HALF 1000
1) Little Endian Byte Ordering where memory address is the address of least significant byte. Example: Intel IA-32, Alpha
2) Big Endian Byte Ordering where memory address is the address of most significant byte. Example: SPARC, PA-RISC
MIPS can operate with both byte orderings
MIPS provides a special syscall instruction to obtain services from the operating system
Services are provided in SPIM using the syscall system services
Load the service number in register $v0
Load argument values, if any, in registers $a0, $a1, etc.
Issue the syscall instruction
Retrieve return values, if any, from result registers
####################################################
# Reading and Printing an Integer
################# Code segment #####################
.text
.globl main
main: # main program entry
li $v0, 5 # Read integer
syscall # $v0 = value read
move $a0, $v0 # $a0 = value to print
li $v0, 1 # Print integer
syscall
li $v0, 10 # Exit program
syscall
####################################################
# Reading and Printing a String
#
################# Data segment #####################
.data
str: .space 10 # array of 10 bytes
################# Code segment #####################
.text
.globl main
main: # main program entry
la $a0, str # $a0 = address of str
li $a1, 10 # $a1 = max string length
li $v0, 8 # read string
syscall
li $v0, 4 # Print string str
syscall
li $v0, 10 # Exit program
syscall
####################################################
# Summing three integers
#
# Objective: Computes the sum of three integers.
# Input: Requests three numbers.
# Output: Outputs the sum.
################### Data segment ###################
.data
prompt: .asciiz "Please enter three numbers: \n"
sum_msg: .asciiz "The sum is: "
################### Code segment ###################
.text
.globl main
main:
la $a0,prompt # display prompt string
li $v0,4
syscall
li $v0,5 # read 1st integer into $t0
syscall
move $t0,$v0
li $v0,5 # read 2nd integer into $t1
syscall
move $t1,$v0
li $v0,5 # read 3rd integer into $t2
syscall
move $t2,$v0
addu $t0,$t0,$t1 # accumulate the sum
addu $t0,$t0,$t2
la $a0,sum_msg # write sum message
li $v0,4
syscall
move $a0,$t0 # output sum
li $v0,1
syscall
li $v0,10 # exit
syscall
#######################################################
# Objective: Convert lowercase letters to uppercase
# Input: Requests a character string from the user.
# Output: Prints the input string in uppercase.
################### Data segment #####################
.data
name_prompt: .asciiz "Please type your name: "
out_msg: .asciiz "Your name in capitals is: "
in_name: .space 31 # space for input string
################### Code segment #####################
.text
.globl main
main:
la $a0,name_prompt # print prompt string
li $v0,4
syscall
la $a0,in_name # read the input string
li $a1,31 # at most 30 chars + 1 null char
li $v0,8
syscall
la $a0,out_msg # write output message
li $v0,4
syscall
la $t0,in_name
loop:
lb $t1,($t0)
beqz $t1,exit_loop # if NULL, we are done
blt $t1,'a',no_change
bgt $t1,'z',no_change
addiu $t1,$t1,-32 # convert to uppercase: 'A'-'a'=-32
sb $t1,($t0)
no_change:
addiu $t0,$t0,1 # increment pointer
j loop
exit_loop:
la $a0,in_name # output converted string
li $v0,4
syscall
li $v0,10 # exit
syscall
swap(a,10)
In assembly you must:
Address MIPS Instruction Assembly Language
00400020 lui $1, 0x1001 la $a0, a
00400024 ori $4, $1, 0
00400028 ori $5, $0, 10 li $a1,10
0040002C jal 0x10000f jal swap
00400030 . . . # return here
swap:
0040003C sll $8, $5, 2 sll $t0,$a1,2
00400040 add $8, $8, $4 add $t0,$t0,$a0
00400044 lw $9, 0($8) lw $t1,0($t0)
00400048 lw $10,4($8) lw $t2,4($t0)
0040004C sw $10,0($8) sw $t2,0($t0)
00400050 sw $9, 4($8) sw $t1,4($t0)
00400054 jr $31 jr $ra
Parameter passing is complicated in Assembly since you DO EVERYTHING!
By convention, registers $s0, $s1, ... , $s7 should be preserved by callee
registers $sp, $fp, and $ra should also be preserved
Caller-saved means registers are saved by the caller in the caller's stack frame before making a procedure call
By convention, registers $t0, ... $t9 should be preserved by caller
##########################################################
# Selection Sort Procedure
# Objective: Sort array using selection sort algorithm
# Input: $a0 = pointer to first, $a1 = pointer to last
# Output: array is sorted in place
##########################################################
sort:
addiu $sp, $sp, -4 # allocate one word on stack
sw $ra, 0($sp) # save return address on stack
top:
jal max # call max procedure
lw $t0, 0($a1) # $t0 = last value
sw $t0, 0($v0) # swap last and max values
sw $v1, 0($a1)
addiu $a1, $a1, -4 # decrement pointer to last
bne $a0, $a1, top # more elements to sort
lw $ra, 0($sp) # pop return address
addiu $sp, $sp, 4
jr $ra # return to caller
##########################################################
# Max Procedure
# Objective: Find the address and value of maximum element
# Input: $a0 = pointer to first, $a1 = pointer to last
# Output: $v0 = pointer to max, $v1 = value of max
##########################################################
max:
move $v0, $a0 # max pointer = first pointer
lw $v1, 0($v0) # $v1 = first value
beq $a0, $a1, ret # if (first == last) return
move $t0, $a0 # $t0 = array pointer
loop:
addi $t0, $t0, 4 # point to next array element
lw $t1, 0($t0) # $t1 = value of A[i]
ble $t1, $v1, skip # if (A[i] <= max) then skip
move $v0, $t0 # found new maximum
move $v1, $t1
skip:
bne $t0, $a1, loop # loop back if more elements
ret:
jr $ra
/* factorial function */
int fact(int n) {
if (n < 2)
return 1;
else
return (n*fact(n-1)); /* nothing happens after the recursive call */
}
fact:
slti $t0,$a0,2 # (n < 2)?
beq $t0,$0,else # if false branch to else
li $v0,1 # $v0 = 1
jr $ra # return to caller
else:
addiu $sp,$sp,-8 # allocate 2 words on stack
sw $a0,4($sp) # save argument n
sw $ra,0($sp) # save return address
addiu $a0,$a0,-1 # argument = n-1
jal fact # call fact(n-1)
lw $a0,4($sp) # restore argument
lw $ra,0($sp) # restore return address
mul $v0,$a0,$v0 # $v0 = n*fact(n-1)
addi $sp,$sp,8 # free stack frame
jr $ra # return to caller