Here are tables of common MIPS instructions and what they do. If you want some in-context examples of when you’d use them, see the cookbook.
All arithmetic and bitwise instructions can be written in two ways:
The i means “immediate,” since numbers inside instructions are called immediates.
Sometimes for this second form, you will see it written like addi or subi . These are completely equivalent, just a different name for the same instruction.
| Mnemonic | Operation | Description |
|---|---|---|
| neg a, b | a = -b | gives the negative of b. |
| add a, b, c | a = b + c | adds signed numbers. |
| sub a, b, c | a = b - c | subtracts signed numbers. |
| mul a, b, c | a = b * c | gives low 32 bits of signed multiplication. |
| div a, b, c | a = b / c | gives quotient of signed division. |
| rem a, b, c | a = b % c | gives remainder of signed division. |
| addu a, b, c | a = b + c | adds unsigned numbers. |
| subu a, b, c | a = b - c | subtracts unsigned numbers. |
| mulu a, b, c | a = b * c | gives low 32 bits of unsigned multiplication. |
| divu a, b, c | a = b / c | gives quotient of unsigned division. |
| remu a, b, c | a = b % c | gives remainder of unsigned division. |
| mfhi a | a = HI | after mul , gives high 32 bits. after div , gives remainder. |
| mflo a | a = LO | after mul , gives low 32 bits. after div , gives quotient. |
| not a, b | a = ~b | gives the bitwise complement of b (all bits flipped). |
| and a, b, c | a = b & c | bitwise ANDs numbers. |
| or a, b, c | a = b | c | bitwise ORs numbers. |
| xor a, b, c | a = b ^ c | bitwise XORs numbers. |
MIPS decided to implement shifts a little differently than the rest of the arithmetic and bitwise instructions.
| Mnemonic | Operation | Description |
|---|---|---|
| sll a, b, imm | a = b | shift left by a constant amount. |
| srl a, b, imm | a = b >>> imm | shift right unsigned (logical) by a constant amount. |
| sra a, b, imm | a = b >> imm | shift right arithmetic by a constant amount. |
| sllv a, b, reg | a = b | shift left by the amount in a register. |
| srlv a, b, reg | a = b >>> reg | shift right unsigned (logical) by the amount in a register. |
| srav a, b, reg | a = b >> reg | shift right arithmetic by the amount in a register. |
There are two “load” instructions which do not access memory. Also, move does not move, it copies. THAT’S LIFE.
| Mnemonic | Operation | Description |
|---|---|---|
| li a, imm | a = imm | put a constant value into a register. |
| la a, label | a = &label | put the address that a label points to into a register. |
| move a, b | ` a = b ` | copy value from one register to another. |
The rest of the load/store instructions always access memory. All of these instructions can be written in three different ways:
.data var: .word 0
REMEMBER: stores copy values FROM registers TO memory. So FROM the left side TO the address on the right side.
| Mnemonic | Operation | Description |
|---|---|---|
| lw reg, addr | reg = MEM[addr] | loads the 4 bytes at addr as a 32-bit value into reg . |
| lh reg, addr | reg = sxt(MEM[addr]) | loads the 2 bytes at addr as a signed 16-bit value into reg . |
| lb reg, addr | reg = sxt(MEM[addr]) | loads the 1 byte at addr as a signed 8-bit value into reg . |
| lhu reg, addr | reg = zxt(MEM[addr]) | loads the 2 bytes at addr as an unsigned 16-bit value into reg . |
| lbu reg, addr | reg = zxt(MEM[addr]) | loads the 1 byte at addr as an unsigned 8-bit value into reg . |
| sw reg, addr | MEM[addr] = reg | stores the value of reg into memory as 4 bytes starting at addr . |
| sh reg, addr | MEM[addr] = lo16(reg) | stores the low 16 bits of reg into memory as 2 bytes starting at addr . |
| sb reg, addr | MEM[addr] = lo8(reg) | stores the low 8 bits of reg into memory as 1 byte at addr . |
Last, there are two stack (pseudo-)instructions which are used to save and restore values in functions:
| Mnemonic | Operation | Description |
|---|---|---|
| push reg | sp -= 4; MEM[sp] = reg | pushes the value of reg onto the call stack |
| pop reg | reg = MEM[sp]; sp += 4 | pops the top call stack value and puts it into reg |
These always change the PC to a new location.
| Mnemonic | Operation | Description |
|---|---|---|
| j label | PC = label | goes to the instruction at label . |
| jal label | ra = PC + 4; PC = label | function call to label . stores return address in ra . |
| jr reg | PC = reg | goes to the instruction whose address is in reg , often ra . |
| syscall | ---> | runs the system call function whose number is in v0 . |
All these instructions check the given condition, and if it’s:
Also, all of these instructions can be written two ways:
| Mnemonic | Operation | Description |
|---|---|---|
| beq a, b, label | if(a == b) | if a is equal to b , goes to label . |
| bne a, b, label | if(a != b) | if a is NOT equal to b , goes to label . |
| blt a, b, label | if(a | if a is less than b , goes to label . |
| ble a, b, label | if(a | if a is less than or equal to b , goes to label . |
| bgt a, b, label | if(a > b) | if a is greater than b , goes to label . |
| bge a, b, label | if(a >= b) | if a is greater than or equal to b , goes to label . |
| bltu a, b, label | if(a | same as blt but does an unsigned comparison. |
| bleu a, b, label | if(a | same as ble but does an unsigned comparison. |
| bgtu a, b, label | if(a > b) | same as bgt but does an unsigned comparison. |
| bgeu a, b, label | if(a >= b) | same as bge but does an unsigned comparison. |