The MIPS instruction set is relatively easy to read since all instructions are 32 bits.
There are 4 types of instructions (though R and FR are basically the same):
 R instructions  where all the data values used by the instruction are located in registers.
 FR instructions  Like the R instructions but used for floating point numbers.
 I instructions  where the instruction must operate on an immediate value and a register value. Immediate values may be a maximum of 16 bits long.
 J instructions  where jumps are needed. The immediate jump offset can be up to 26 bits
See: https://en.wikibooks.org/wiki/MIPS_Assembly/Instruction_Formats
MIPS overview[edit  edit source]
Instruction  Name  Action  Fields  

R instruction  Used when all the data values used by the instruction are located in registers.  Opcode
6 bits 
Reg Source
(rs, 5 bits) 
Reg Source
(rt, 5 bits) 
Reg Dest
(rd, 5 bits) 
Shift
(shamt) 5 bits 
Function
6 bits  
I instruction  Used when the instruction must operate on an immediate value and a register value.
Immediate values may be a maximum of 16 bits long. 
Opcode
6 bits 
Reg Source
(rs, 5 bits) 
Reg Source
(rt, 5 bits) 
Immediate value
16 bits  
J instruction  Used when jumps are needed.
The immediate jump offset can be up to 26 bits 
Opcode
6 bits 
Address (26 bits)  
Arithmetic Logic Unit  
ADD rd, rs, rt

Add  rd = rs + rt

000000  rs  rt  rd  00000  100000 
ADDI rt, rs, imm

Add Immediate  rt = rs + imm

001000  rs  rt  imm  
ADDIU rt, rs, imm

Add Immediate Unsigned (no 2's complement)  rt = rs + imm

001001  rs  rt  imm  
ADDU rd, rs, rt

Add Unsigned  rd = rs + rt

000000  rs  rt  rd  00000  100001 
SUB rd, rs, rt

Subtract  rd = rs  rt

000000  rs  rt  rd  00000  100010 
SUBU rd, rs, rt

Subtract Unsigned  rd = rs  rt

000000  rs  rt  rd  00000  100011 
AND rd, rs, rt

And  rd = rs & rt

000000  rs  rt  rd  00000  100100 
ANDI rt, rs, imm

And Immediate  rt = rs & imm

001100  rs  rt  imm  
NOR rd, rs, rt

NOR  rd = ~(rsrt)

000000  rs  rt  rd  00000  100111 
OR rd, rs, rt

OR  rd = rsrt

000000  rs  rt  rd  00000  100101 
ORI rt, rs, imm

OR Immediate  rt = rsimm

001101  rs  rt  imm  
SLT rd, rs, rt

Set On Less Than  rd = (rs < rt) ? 1 : 0

000000  rs  rt  rd  00000  101010 
SLTI rt, rs, imm

Set On Less Than Immediate  rt = (rs < imm) ? 1 : 0

001010  rs  rt  imm  
SLTIU rt, rs, imm

Set On < Immediate Unsigned  rt = (rs < imm) ? 1 : 0

001011  rs  rt  imm  
SLTU rd, rs, rt

Set On Less Than Unsigned  rd = (rs < rt) ? 1 : 0

000000  rs  rt  rd  00000  101011 
XOR rd, rs, rt

Exclusive OR  rd = rs ^ rt

000000  rs  rt  rd  00000  100110 
XORI rt, rs, imm

Exclusive OR Immediate  rt = rs ^ imm

001110  rs  rt  imm  
Logical Shifts  
SLL rd, rt, sa

Shift Left Logical  rd = rt << sa

000000  rs  rt  rd  sa  000000 
SLLV rd, rt, rs

Shift Left Logical Variable  rd = rt << rs

000000  rs  rt  rd  00000  000100 
SRA rd, rt, sa

Shift Right Arithmetic  rd = rt >> sa

000000  rs=00000  rt  rd  sa  000011 
SRAV rd, rt, rs

Shift Right Arithmetic Variable  rd = rt >> rs

000000  rs  rt  rd  00000  000111 
SRL rd, rt, sa

Shift Right Logical  rd = rt >> sa

000000  rs  rt  rd  sa  000010 
SRLV rd, rt, rs

Shift Right Logical Variable  rd = rt >> rs

000000  rs  rt  rd  00000  000110 
Multiply  
DIV rs, rt

Divide  HI= rs % rt; LO = rs/rt

000000  rs  rt  0000000000  011010  
DIVU rs, rt

Divide Unsigned  HI= rs % rt; LO = rs/rt

000000  rs  rt  0000000000  011011  
MFHI rd

Move From HI  rd = HI

000000  0000000000  rd  00000  010000  
MFLO rd

Move From LO  rd = LO

000000  0000000000  rd  00000  010010  
MTHI rs

Move To HI register  HI= rs

000000  rs  000000000000000  010001  
MTLO rs

Move To LO register  LO = rs

000000  rs  000000000000000  010011  
MULT rs, rt

Multiply  HI, LO = rs*rt

000000  rs  rt  0000000000  011000  
MULTU rs, rt

Multiply Unsigned  HI, LO = rs*rt

000000  rs  rt  0000000000  011001  
Branch  
BEQ rs, rt, offset

Branch On Equal  if (rs == rt) pc = pc + 4 + offset

000100  rs  rt  offset  
BGEZ rs, offset

Branch On >= 0  if (rs >= 0) pc = pc + 4 + offset

000001  rs  rt=00001  offset  
BGEZAL rs, offset

Branch On >= 0 and link. Saves return address in $ra  $ra = pc; if (rs>= 0) pc = pc + 4 + offset

000001  rs  rt=10001  offset  
BGTZ rs, offset

Branch On > 0  if (rs>0) pc = pc + 4 + offset

000111  rs  rt=00000  offset  
BLEZ rs, offset

Branch On  if (rs<= 0) pc = pc + 4 + offset

000110  rs  rt=00000  offset  
BLTZ rs, offset

Branch On < 0  if (rs<0) pc = pc + 4 + offset

000001  rs  rt=00000  offset  
BLTZAL rs, offset

Branch On < 0 and link. Saves return address in $ra  $ra = pc; if (rs<0) pc = pc + 4 + offset

000001  rs  rt=10000  offset  
BNE rs, rt, offset

Branch On Not Equal  if (rs != rt) pc = pc + 4 + offset

000101  rs  rt  offset  
bgt $1,$2,100

branch on greater than  if ($1 > $2) pc = pc + 4 + 100

Pseudo instruction  
bge $1,$2,100

branch on greater than or equal  if ($1 >= $2) pc = pc + 4 + 100

Pseudo instruction  
blt $1,$2,100

branch on less than  if ($1 < $2) pc = pc + 4 + 100

Pseudo instruction  
ble $1,$2,100

branch on less than or equal  if ($1 <= $2) pc = pc + 4 + 100

Pseudo instruction  
BREAK

Breakpoint  epc = pc; pc = 0x3c

000000  code  001101  
J target

Jump  pc = pc_upper(target<<2)

000010  target  
JAL target

Jump and link.
Saves return address in $ra 
$ra = pc + 4; pc = target<<2

000011  target  
JR rs

Jump register  pc = rs

000000  rs  rt=00000  rd=00000  00000  001000 
JALR rs

Jump and link register.
Like JR, but return address saved in specified register. 
$ra = pc + 4; pc = rs

000000  rs  rt=00000  rd  00000  001001 
MFC0 rt, rd

Move From Coprocessor  rt = CPR[0, rd]

010000  00000  rt  rd  00000000000  
MTC0 rt, rd

Move To Coprocessor  CPR[0, rd]= rt

010000  00100  rt  rd  00000000000  
SYSCALL

System Call  epc = pc; pc = 0x3c

000000  00000000000000000000  001100  
Memory Access  
LB rt, imm(rs)

Load Byte  rt = (char) Mem[rs + imm]

100000  rs  rt  imm  
LBU rt, imm(rs)

Load Byte Unsigned  rt = (uchar) Mem[rs + imm]

100100  rs  rt  imm  
LH rt, imm(rs)

Load Halfword, 2 bytes  rt = (short) Mem[rs + imm]

100001  rs  rt  imm  
LHU rt, imm(rs)

Load Halfword Unsigned  rt = (ushort) Mem[rs + imm]

100101  rs  rt  imm  
LW rt, imm(rs)

Load Word, 4 bytes.  rt = Mem[rs + imm]

100011  rs  rt  imm  
LUI rt, imm

Load Upper Immediate  rt = imm << 16

001111  rs=00000  rt  imm  
SB rt, imm(rs)

Store (least significant) byte  Mem[rs + imm] = (byte) rt

101000  rs  rt  imm  
SH rt, imm(rs)

Store (least significant) halfword content of rt  Mem[rs + imm] = (short) rt

101001  rs  rt  imm  
SW rt, imm(rs)

Store content of rt in memory  Mem[rs + imm] = rt

101011  rs  rt  imm 
Pseudo instructions[edit  edit source]
There are pseudo instructions that are provided by your assembler and are converted to multiple instructions. Think of these as assembler macros.
See: https://en.wikibooks.org/wiki/MIPS_Assembly/Pseudoinstructions
move $1, $2

Move data from one register to another  $1 = $2

li $1,100

Loads immediate value into register  $1 = 100

la $1,label

Loads computed address of label (not its contents) into register  $1 = Address of label

bgt $1,$2,100

branch on greater than  if ($1 > $2) pc = pc + 4 + 100

bge $1,$2,100

branch on greater than or equal  if ($1 >= $2) pc = pc + 4 + 100

blt $1,$2,100

branch on less than  if ($1 < $2) pc = pc + 4 + 100

ble $1,$2,100

branch on less than or equal  if ($1 <= $2) pc = pc + 4 + 100

abs $1, $2

Puts the absolute value from one register ao another  $1 = abs($2) 
neg


negu


not


sge


sgt


NOP

No operation. This can be done by running SLL $0 $0 $0 or 32bits of 0's.

Registers[edit  edit source]
All the register fields are 5 bits in size giving us 32 registers in total to work with.
All 32 registers are listed in the following table.
Register  Decimal  Binary  Comments 

$zero

$0

00000

Always zero 
$at

$1

00001

used for temporary values within pseudo commands 
$v0

$2

00010

used for returning values from functions
first and second, respectively. 
$v1

$3

00011
 
$a0

$4

00100

used for the first 4 function arguments. 
$a1

$5

00101
 
$a2

$6

00110
 
$a3

$7

00111
 
$t0

$8

01000

temporary registers. 8 in total 
$t1

$9

01001
 
$t2

$10

01010
 
$t3

$11

01011
 
$t4

$12

01100
 
$t5

$13

01101
 
$t6

$14

01110
 
$t7

$15

01111
 
$s0

$16

10000

Saved values representing final computed results 
$s1

$17

10001
 
$s2

$18

10010
 
$s3

$19

10011
 
$s4

$20

10100
 
$s5

$21

10101
 
$s6

$22

10110
 
$s7

$23

10111
 
$t8

$24

11000

Two additional temporary registers 
$t9

$25

11001
 
$k0

$26

11010

Registers reserved for the kernel / operating system 
$k1

$27

11011
 
$gp

$28

11100

Global pointer 
$sp

$29

11101

Stack pointer 
$fp

$30

11110

Frame pointer 
$ra

$31

11111

Return address 