Summary Checklist
Bit Arrangement
Bit Arrangement
opcode |
$rs |
$rt |
$rd |
shamt |
funct |
---|---|---|---|---|---|
6 | 5 | 5 | 5 | 5 | 6 |
opcode |
$rs |
$rt |
immediate |
---|---|---|---|
6 | 5 | 5 | 16 |
opcode |
immediate |
---|---|
6 | 26 |
The full comparison where the bits are aligned is shown below. The number of bits is shown inside a square bracket.
Format | Fields | |||||
---|---|---|---|---|---|---|
R-Format | opcode [6] | $rs [5] | $rt [5] | $rd [5] | shamt [5] | funct [6] |
I-Format | opcode [6] | $rs [5] | $rt [5] | immediate [16] | ||
J-Format | opcode [6] | immediate [26] |
or to put it in picture:
Note
- Branches and load/store are both I-format instructions.
- Branches use PC-relative addressing.
- Load/store use base addressing.
- Shifts use R-format but other immediate instructions (i.e.,
addi
,andi
,ori
,slti
) use I-format. - J-format use pseudo-direct addressing.
- Compared to branches which use PC-relative addressing.
Opcode/Funct Values
Funct Values
Operation | Hexadecimal | Decimal |
---|---|---|
add |
20 | 32 |
sub |
22 | 34 |
sll |
00 | 00 |
srl |
02 | 02 |
and |
24 | 36 |
or |
25 | 37 |
xor |
26 | 38 |
nor |
27 | 39 |
Opcode Values
Operation | Hexadecimal | Decimal |
---|---|---|
R-Format | 00 | 00 |
j |
02 | 02 |
beq |
04 | 04 |
bne |
05 | 05 |
addi |
08 | 08 |
andi |
0C | 12 |
ori |
0D | 13 |
xori |
0E | 14 |
lb |
20 | 32 |
lw |
23 | 35 |
sb |
28 | 40 |
sw |
2B | 43 |
Immediate Field
Branch
Branch Calculation
-
If the branch is not taken:
$PC' = $PC + 4
-
If the branch is taken:
$PC' = ($PC + 4) + (immediate × 4)
Here, $PC + 4
is the address of the next instruction and $PC'
is the target address.
Why do we use $PC + 4
when the branch is not taken?
The reason will be clearer when we show the processor implementation.
The advantage of this computation is that the immediate value specifies the number of instruction to "skip over" (from the next instruction).
Quick Branch Calculation
The immediate value specifies the number of instruction to "skip over" (from the next instruction).
-
Draw a line below the current instruction (this represents the
$PC + 4
). -
Draw a line above the target instruction (this represents the
$PC'
). -
Complete the box.
-
Count the number of instructions within the box (this represents the
immediate × 4
).- If the target label is after, keep the value as positive.
- If the target label is before, convert the value to negative.
Jump
Address Calculation
-
Without bitwise operations:
$PC' = ($PC + 4) - (($PC + 4) % 268435456) + (immediate × 4)
-
With bitwise operations:
$PC' = (($PC + 4) & 0xF0000000) | (immediate × 4)
Here, $PC + 4
is the address of the next instruction and $PC'
is the target address.
268435456 is equal to 228.
Now, calculating the address is probably more difficult due to the magic number.
So, we will also illustrate it with a diagram below.
Summary Table
The following summary shows only selective instructions. Hopefully you can extrapolate this to other instructions of similar kinds.
Do NOT Sort
There is a bug in the table sorting mechanism due to some cell spanning multiple rows. If you accidentally sort the table, simply reload the page.
Category | Instruction | Example | Meaning | Comments |
---|---|---|---|---|
Arithmetic | Addition | add $rd, $rs, $rt | $rd = $rs + $rt | 3 operands; register addressing |
Subtraction | sub $rd, $rs, $rt | $rd = $rs - $rt | 3 operands; register addressing | |
Add Immediate | addi $rt, $rs, imm | $rt = $rs + imm | Used to add constants | |
Data Transfer | Load Word | lw $rt, offset($rs) | $rt = MEM[$rs + offset] | Word from memory to register |
Store Word | sw $rt, offset($rs) | MEM[$rs + offset] = $rt | Word from register to memory | |
Load Byte | lb $rt, offset($rs) | $rt = MEM[$rs + offset] | Byte from memory to register | |
Store Byte | sb $rt, offset($rs) | MEM[$rs + offset] = $rt | Byte from register to memory | |
Load Upper Immediate | lui $rt, imm | $rt = imm << 16 or $rt = imm × 216 | Load cosntant in upper 16 bits | |
Branch | Branch on Equal | beq $rs, $rt, imm | $PC = ($rs == $rt) ? ($PC+4)+(imm×4) : ($PC+4) | Equal test; PC-relative branch |
Branch on Not Equal | bne $rs, $rt, imm | $PC = ($rs != $rt) ? ($PC+4)+(imm×4) : ($PC+4) | Not equal test; PC-relative branch | |
Set on Less Than | slt $rd, $rs, $rt | $rd = ($rs < $rt) ? 1 : 0 | Compare less than; for beq or bne | |
Set on Less Than Immediate | slti $rt, $rs, imm | $rt = ($rs < imm) ? 1 : 0 | Compare less than constant; for beq or bne | |
Jump | Jump | j imm | $PC = (($PC+4) & 0xF0000000) | (imm×4)) | Jump to target address; pseudo-direct addressing |
Jump Register | jr $ra | $PC = $ra | For switch, procedure return | |
Jump and Link | jal imm | $ra = $PC+4 then $PC = (($PC+4) & 0xF0000000) | (imm×4)) | For procedure call |
MIPS Assembler
We have a MIPS assembler that admits the same MIPS syntax as MIPS interpreter.
To correctly assemble j
instruction, you will need to specify the base address (i.e., the address of the first instruction of the program).
This base address will need to be word-aligned (i.e., multiple of 4).
If none is specified, it will be assumed to be 0.
Note that the base address should be specified as hexadecimal without the prefix 0x.
Currently, the assembler assumes that the code can be assembled correctly. As such, it does not check if there is a jump at the boundary.