2018-06-17 20:02:17 +03:00
|
|
|
---
|
2018-07-09 04:32:51 +03:00
|
|
|
language: "MIPS Assembly"
|
|
|
|
filename: MIPS.asm
|
2018-06-17 20:02:17 +03:00
|
|
|
contributors:
|
|
|
|
- ["Stanley Lim", "https://github.com/Spiderpig86"]
|
|
|
|
---
|
|
|
|
|
2018-07-09 04:16:51 +03:00
|
|
|
The MIPS (Microprocessor without Interlocked Pipeline Stages) Assembly language
|
|
|
|
is designed to work with the MIPS microprocessor paradigm designed by J. L.
|
|
|
|
Hennessy in 1981. These RISC processors are used in embedded systems such as
|
|
|
|
gateways and routers.
|
2018-06-17 20:02:17 +03:00
|
|
|
|
|
|
|
[Read More](https://en.wikipedia.org/wiki/MIPS_architecture)
|
|
|
|
|
|
|
|
```assembly
|
|
|
|
# Comments are denoted with a '#'
|
|
|
|
|
|
|
|
# Everything that occurs after a '#' will be ignored by the assembler's lexer.
|
2018-06-24 21:00:07 +03:00
|
|
|
|
|
|
|
# Programs typically contain a .data and .text sections
|
|
|
|
|
2018-07-09 04:16:51 +03:00
|
|
|
.data # Section where data is stored in memory (allocated in RAM), similar to
|
|
|
|
variables in higher level languages
|
2018-06-24 21:00:07 +03:00
|
|
|
|
|
|
|
# Declarations follow a ( label: .type value(s) ) form of declaration
|
2018-06-24 21:55:47 +03:00
|
|
|
hello_world .asciiz "Hello World\n" # Declare a null terminated string
|
2018-07-09 04:16:51 +03:00
|
|
|
num1: .word 42 # Integers are referred to as words
|
|
|
|
# (32 bit value)
|
|
|
|
|
2018-06-24 21:55:47 +03:00
|
|
|
arr1: .word 1, 2, 3, 4, 5 # Array of words
|
|
|
|
arr2: .byte 'a', 'b' # Array of chars (1 byte each)
|
2018-07-09 04:16:51 +03:00
|
|
|
buffer: .space 60 # Allocates space in the RAM
|
|
|
|
# (not cleared to 0)
|
2018-06-24 21:00:07 +03:00
|
|
|
|
|
|
|
# Datatype sizes
|
2018-06-24 21:55:47 +03:00
|
|
|
_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
|
2018-06-24 21:00:07 +03:00
|
|
|
|
2018-07-09 04:16:51 +03:00
|
|
|
.align 2 # Memory alignment of data, where
|
|
|
|
# number indicates byte alignment in
|
|
|
|
# powers of 2. (.align 2 represents
|
2018-07-09 04:32:51 +03:00
|
|
|
# word alignment since 2^2 = 4 bytes)
|
2018-06-24 21:55:47 +03:00
|
|
|
|
2018-07-09 04:16:51 +03:00
|
|
|
.text # Section that contains instructions
|
|
|
|
# and program logic
|
|
|
|
.globl _main # Declares an instruction label as
|
|
|
|
# global, making it accessible to
|
|
|
|
# other files
|
2018-06-24 21:55:47 +03:00
|
|
|
|
2018-07-09 04:16:51 +03:00
|
|
|
_main: # MIPS programs execute instructions
|
|
|
|
# sequentially, where the code under
|
|
|
|
# this label will be executed firsts
|
2018-06-24 21:55:47 +03:00
|
|
|
|
|
|
|
# Let's print "hello world"
|
2018-07-09 04:16:51 +03:00
|
|
|
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)
|
2018-06-24 21:55:47 +03:00
|
|
|
|
|
|
|
# Registers (used to hold data during program execution)
|
2018-07-09 04:16:51 +03:00
|
|
|
# $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
|
2018-06-24 21:55:47 +03:00
|
|
|
|
|
|
|
# Types of load/store instructions
|
2018-07-09 04:16:51 +03:00
|
|
|
la $t0, label # Copy the address of a value in
|
|
|
|
# memory specified by the label into
|
|
|
|
# register $t0
|
2018-06-24 21:55:47 +03:00
|
|
|
lw $t0, label # Copy a word value from memory
|
2018-07-09 04:16:51 +03:00
|
|
|
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
|
2018-06-24 21:55:47 +03:00
|
|
|
# Same idea with 'lh' for halfwords
|
|
|
|
|
2018-07-09 04:16:51 +03:00
|
|
|
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
|
2018-06-24 21:55:47 +03:00
|
|
|
# Same idea using 'sb' and 'sh' for bytes and halfwords. 'sa' does not exist
|
2018-06-24 21:00:07 +03:00
|
|
|
|
2018-07-07 19:08:10 +03:00
|
|
|
### Math ###
|
|
|
|
_math:
|
|
|
|
# Remember to load your values into a register
|
2018-07-08 22:05:27 +03:00
|
|
|
lw $t0, num # From the data section
|
|
|
|
li $t0, 5 # Or from an immediate (constant)
|
2018-07-07 19:08:10 +03:00
|
|
|
li $t1, 6
|
2018-07-08 22:16:26 +03:00
|
|
|
add $t2, $t0, $t1 # $t2 = $t0 + $t1
|
|
|
|
sub $t2, $t0, $t1 # $t2 = $t0 - $t1
|
|
|
|
mul $t2, $t0, $t1 # $t2 = $t0 * $t1
|
2018-07-09 04:16:51 +03:00
|
|
|
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'
|
2018-07-08 22:05:27 +03:00
|
|
|
|
|
|
|
# Bitwise Shifting
|
2018-07-09 04:16:51 +03:00
|
|
|
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
|
2018-07-08 22:05:27 +03:00
|
|
|
|
|
|
|
# Bitwise operators
|
2018-07-08 22:16:26 +03:00
|
|
|
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
|
2018-07-07 19:08:10 +03:00
|
|
|
|
2018-06-17 20:02:17 +03:00
|
|
|
```
|