Compilers take high-level code (like C) and turn it into machine code. MIPS was designed to be easy for compilers to generate code for.

You can learn the same rules that compilers use to turn any high-level pseudocode into MIPS just by following some rules. They’re BRAIN ALGORITHMS.

Variables

Assuming you have some global variables like this:

.data
x: .word 10
y: .word 20
.text

Description C MIPS Notes
Get value x lw t0, x The type of load instruction
must match the variable type.
Set value x = 30 li t0, 30
sw t0, x
The type of store instruction
must match the variable type.
Read-modify-write x++ lw t0, x
add t0, t0, 1
sw t0, x
Combine the above two.
Copy variable x = y lw t0, y
sw t0, x
Same idea.

Arrays

Arrays are just variables sitting next to each other. They’re spooning.

Making an array: int array[] = {1, 2, 3, 4, 5};

.data
array: .word 1, 2, 3, 4, 5
.text


Getting a value: array[i]

Assume i is represented by s0.

	la  t0, array  # t0 = A:  get base address
mul t1, s0, 4  # t1 = Bi: multiply index by size of *one item in the array*
add t0, t0, t1 # t0 = A + Bi
lw  t1, (t0)   # t1 = array[i]


If the array is an array of bytes, you can skip the mul step - since you’d be multiplying by 1.

Setting a value: array[i] = 10

Assume i is represented by s0.

	# exactly the same address calculation as above!
la  t0, array  # t0 = A:  get base address
mul t1, s0, 4  # t1 = Bi: multiply index by size of one item in the array
add t0, t0, t1 # t0 = A + Bi

# just this differs.
li	t1, 10     # t1 = 10
sw  t1, (t0)   # array[i] = 10


Function calls

For writing functions, see the cookbook instead.

There are two (or three) steps:

1. Put the arguments in the argument registers, starting with a0
2. Call the function
3. If it returns something, the return value is in v0.

A handful of syscalls (30, 41, 42, 50, 51, 52, 53, 54) return values in a0 and a1 instead. I have no idea why.

Calling a syscall: print_int(10)

	li a0, 10
li v0, 1 # number of print_int syscall
syscall


Calling a syscall that returns something: x = read_int()

	# no arguments!
li v0, 5 # number of read_int syscall
syscall
sw v0, x # return value is in v0


Calling a regular function: addPoints(50)

	li  a0, 50