0% found this document useful (0 votes)
150 views

Mips Assembly

The document summarizes key aspects of MIPS assembly language code structure and instructions. It describes the .data and .text sections for storing data and code respectively. Common data types and memory allocation directives are shown. Key registers are identified along with load, store, arithmetic, logical, and branching instructions. Loops and simple conditional logic examples are also provided.

Uploaded by

Denes Marschalko
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
150 views

Mips Assembly

The document summarizes key aspects of MIPS assembly language code structure and instructions. It describes the .data and .text sections for storing data and code respectively. Common data types and memory allocation directives are shown. Key registers are identified along with load, store, arithmetic, logical, and branching instructions. Loops and simple conditional logic examples are also provided.

Uploaded by

Denes Marschalko
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

# Comments are denoted with a '#'

# Everything that occurs after a '#' will be ignored by the assembler's lexer.

# Programs typically contain a .data and .text sections

.data # Section where data is stored in memory (allocated in RAM), similar to


# variables in higher level languages

# Declarations follow a ( label: .type value(s) ) form of declaration


hello_world: .asciiz "Hello World\n" # Declare a null terminated string
num1: .word 42 # Integers are referred to as words
# (32 bit value)

arr1: .word 1, 2, 3, 4, 5 # Array of words


arr2: .byte 'a', 'b' # Array of chars (1 byte each)
buffer: .space 60 # Allocates space in the RAM
# (not cleared to 0)

# Datatype sizes
_byte: .byte 'a' # 1 byte
_halfword: .half 53 # 2 bytes
_word: .word 3 # 4 bytes
_float: .float 3.14 # 4 bytes
_double: .double 7.0 # 8 bytes

.align 2 # Memory alignment of data, where


# number indicates byte alignment in
# powers of 2. (.align 2 represents
# word alignment since 2^2 = 4 bytes)

.text # Section that contains instructions


# and program logic
.globl _main # Declares an instruction label as
# global, making it accessible to
# other files

_main: # MIPS programs execute instructions


# sequentially, where the code under
# this label will be executed firsts

# Let's print "hello world"


la $a0, hello_world # Load address of string stored in
# memory
li $v0, 4 # Load the syscall value (indicating
# type of functionality)
syscall # Perform the specified syscall with
# the given argument ($a0)

# Registers (used to hold data during program execution)


# $t0 - $t9 # Temporary registers used for
# intermediate calculations inside
# subroutines (not saved across
# function calls)

# $s0 - $s7 # Saved registers where values are


# saved across subroutine calls.
# Typically saved in stack
# $a0 - $a3 # Argument registers for passing in
# arguments for subroutines
# $v0 - $v1 # Return registers for returning
# values to caller function

# Types of load/store instructions


la $t0, label # Copy the address of a value in
# memory specified by the label into
# register $t0
lw $t0, label # Copy a word value from memory
lw $t1, 4($s0) # Copy a word value from an address
# stored in a register with an offset
# of 4 bytes (addr + 4)
lb $t2, label # Copy a byte value to the lower order
# portion of the register $t2
lb $t2, 0($s0) # Copy a byte value from the source
# address in $s0 with offset 0
# Same idea with 'lh' for halfwords

sw $t0, label # Store word value into memory address


# mapped by label
sw $t0, 8($s0) # Store word value into address
# specified in $s0 and offset of 8
bytes
# Same idea using 'sb' and 'sh' for bytes and halfwords. 'sa' does not exist

### Math ###


_math:
# Remember to load your values into a register
lw $t0, num # From the data section
li $t0, 5 # Or from an immediate (constant)
li $t1, 6
add $t2, $t0, $t1 # $t2 = $t0 + $t1
sub $t2, $t0, $t1 # $t2 = $t0 - $t1
mul $t2, $t0, $t1 # $t2 = $t0 * $t1
div $t2, $t0, $t1 # $t2 = $t0 / $t1 (Might not be
# supported in some versons of MARS)
div $t0, $t1 # Performs $t0 / $t1. Get the quotient
# using 'mflo' and remainder using
'mfhi'

# Bitwise Shifting
sll $t0, $t0, 2 # Bitwise shift to the left with
# immediate (constant value) of 2
sllv $t0, $t1, $t2 # Shift left by a variable amount in
# register
srl $t0, $t0, 5 # Bitwise shift to the right (does
# not sign preserve, sign-extends with
0)
srlv $t0, $t1, $t2 # Shift right by a variable amount in
# a register
sra $t0, $t0, 7 # Bitwise arithmetic shift to the right

# (preserves sign)
srav $t0, $t1, $t2 # Shift right by a variable amount
# in a register

# Bitwise operators
and $t0, $t1, $t2 # Bitwise AND
andi $t0, $t1, 0xFFF # Bitwise AND with immediate
or $t0, $t1, $t2 # Bitwise OR
ori $t0, $t1, 0xFFF # Bitwise OR with immediate
xor $t0, $t1, $t2 # Bitwise XOR
xori $t0, $t1, 0xFFF # Bitwise XOR with immediate
nor $t0, $t1, $t2 # Bitwise NOR

## BRANCHING ##
_branching:
# The basic format of these branching instructions typically follow <instr>
# <reg1> <reg2> <label> where label is the label we want to jump to if the
# given conditional evaluates to true
# Sometimes it is easier to write the conditional logic backwards, as seen
# in the simple if statement example below

beq $t0, $t1, reg_eq # Will branch to reg_eq if


# $t0 == $t1, otherwise
# execute the next line
bne $t0, $t1, reg_neq # Branches when $t0 != $t1
b branch_target # Unconditional branch, will always
execute
beqz $t0, req_eq_zero # Branches when $t0 == 0
bnez $t0, req_neq_zero # Branches when $t0 != 0
bgt $t0, $t1, t0_gt_t1 # Branches when $t0 > $t1
bge $t0, $t1, t0_gte_t1 # Branches when $t0 >= $t1
bgtz $t0, t0_gt0 # Branches when $t0 > 0
blt $t0, $t1, t0_gt_t1 # Branches when $t0 < $t1
ble $t0, $t1, t0_gte_t1 # Branches when $t0 <= $t1
bltz $t0, t0_lt0 # Branches when $t0 < 0
slt $s0, $t0, $t1 # Instruction that sends a signal when
# $t0 < $t1 with reuslt in $s0 (1 for
true)

# Simple if statement
# if (i == j)
# f = g + h;
# f = f - i;

# Let $s0 = f, $s1 = g, $s2 = h, $s3 = i, $s4 = j


bne $s3, $s4, L1 # if (i !=j)
add $s0, $s1, $s2 # f = g + h

L1:
sub $s0, $s0, $s3 # f = f - i

# Below is an example of finding the max of 3 numbers


# A direct translation in Java from MIPS logic:
# if (a > b)
# if (a > c)
# max = a;
# else
# max = c;
# else
# max = b;
# else
# max = c;

# Let $s0 = a, $s1 = b, $s2 = c, $v0 = return register


ble $s0, $s1, a_LTE_b # if (a <= b) branch(a_LTE_b)
ble $s0, $s2, max_C # if (a > b && a <=c) branch(max_C)
move $v0, $s1 # else [a > b && a > c] max = a
j done # Jump to the end of the program

a_LTE_b: # Label for when a <= b


ble $s1, $s2, max_C # if (a <= b && b <= c) branch(max_C)
move $v0, $s1 # if (a <= b && b > c) max = b
j done # Jump to done

max_C:
move $v0, $s2 # max = c

done: # End of program

## LOOPS ##
_loops:
# The basic structure of loops is having an exit condition and a jump
instruction to continue its execution
li $t0, 0
while:
bgt $t0, 10, end_while # While $t0 is less than 10, keep
iterating
addi $t0, $t0, 1 # Increment the value
j while # Jump back to the beginning of the
loop
end_while:

# 2D Matrix Traversal
# Assume that $a0 stores the address of an integer matrix which is 3 x 3
li $t0, 0 # Counter for i
li $t1, 0 # Counter for j
matrix_row:
bgt $t0, 3, matrix_row_end

matrix_col:
bgt $t1, 3, matrix_col_end

# Do stuff

addi $t1, $t1, 1 # Increment the col counter


matrix_col_end:

# Do stuff

addi $t0, $t0, 1


matrix_row_end:

## FUNCTIONS ##
_functions:
# Functions are callable procedures that can accept arguments and return
values all denoted with labels, like above

main: # Programs begin with main func


jal return_1 # jal will store the current PC in $ra
# and then jump to return_1

# What if we want to pass in args?


# First we must pass in our parameters to the argument registers
li $a0, 1
li $a1, 2
jal sum # Now we can call the function

# How about recursion?


# This is a bit more work since we need to make sure we save and restore
# the previous PC in $ra since jal will automatically overwrite on each call
li $a0, 3
jal fact

li $v0, 10
syscall

# This function returns 1


return_1:
li $v0, 1 # Load val in return register $v0
jr $ra # Jump back to old PC to continue exec

# Function with 2 args


sum:
add $v0, $a0, $a1
jr $ra # Return

# Recursive function to find factorial


fact:
addi $sp, $sp, -8 # Allocate space in stack
sw $s0, ($sp) # Store reg that holds current num
sw $ra, 4($sp) # Store previous PC

li $v0, 1 # Init return value


beq $a0, 0, fact_done # Finish if param is 0

# Otherwise, continue recursion


move $s0, $a0 # Copy $a0 to $s0
sub $a0, $a0, 1
jal fact

mul $v0, $s0, $v0 # Multiplication is done

fact_done:
lw $s0, ($sp)
lw $ra, ($sp) # Restore the PC
addi $sp, $sp, 8

jr $ra

## MACROS ##
_macros:
# Macros are extremly useful for substituting repeated code blocks with a
# single label for better readability
# These are in no means substitutes for functions
# These must be declared before it is used

# Macro for printing new lines (since these can be very repetitive)
.macro println()
la $a0, newline # New line string stored here
li $v0, 4
syscall
.end_macro
println() # Assembler will copy that block of
# code here before running

# Parameters can be passed in through macros.


# These are denoted by a '%' sign with any name you choose
.macro print_int(%num)
li $v0, 1
lw $a0, %num
syscall
.end_macro

li $t0, 1
print_int($t0)

# We can also pass in immediates for macros


.macro immediates(%a, %b)
add $t0, %a, %b
.end_macro

immediates(3, 5)

# Along with passing in labels


.macro print(%string)
la $a0, %string
li $v0, 4
syscall
.end_macro

print(hello_world)

## ARRAYS ##
.data
list: .word 3, 0, 1, 2, 6 # This is an array of words
char_arr: .asciiz "hello" # This is a char array
buffer: .space 128 # Allocates a block in memory, does
# not automatically clear
# These blocks of memory are aligned
# next each other

.text
la $s0, list # Load address of list
li $t0, 0 # Counter
li $t1, 5 # Length of the list

loop:
bgt $t0, $t1, end_loop

lw $a0, ($s0)
li $v0, 1
syscall # Print the number

addi $s0, $s0, 4 # Size of a word is 4 bytes


addi $t0, $t0, 1 # Increment
j loop
end_loop:

## INCLUDE ##
# You do this to import external files into your program (behind the scenes,
# it really just takes whatever code that is in that file and places it where
# the include statement is)
.include "somefile.asm"

You might also like