This guide walks through translating MIPS assembly instructions into 32-bit machine code (binary and hex) for every instruction type: R-type, I-type, and J-type. Each example shows the full field-by-field breakdown.
Table of Contents
- Instruction Format Reference
- R-Type Instructions
- I-Type Instructions
- J-Type Instructions
- Complete Program Example
- Full Summary Table
- Encoding Tips & Checklist
1. Instruction Format Reference
All MIPS instructions are exactly 32 bits wide. There are three formats:
R-type: [ op:6 | rs:5 | rt:5 | rd:5 | shamt:5 | funct:6 ] add $t2, $t0, $t1 add rd, rs, rt
I-type: [ op:6 | rs:5 | rt:5 | immediate:16 ] addi $t1, $t0, 100 addi rt, rs, 100 : $t1 = $t0 + 100
J-type: [ op:6 | target:26 ]
1.1 Register Numbers
| Register | Name | Number | 5-bit binary |
|---|---|---|---|
| $0 | $zero | 0 | 00000 |
| $2 | $v0 | 2 | 00010 |
| $4 | $a0 | 4 | 00100 |
| $8 | $t0 | 8 | 01000 |
| $9 | $t1 | 9 | 01001 |
| $10 | $t2 | 10 | 01010 |
| $11 | $t3 | 11 | 01011 |
| $16 | $s0 | 16 | 10000 |
| $17 | $s1 | 17 | 10001 |
| $18 | $s2 | 18 | 10010 |
| $29 | $sp | 29 | 11101 |
| $31 | $ra | 31 | 11111 |
1.2 Opcode / Funct Reference
| Instruction | Format | op (6-bit) | funct (6-bit) |
|---|---|---|---|
| add | R | 000000 |
100000 (32) |
| sub | R | 000000 |
100010 (34) |
| and | R | 000000 |
100100 (36) |
| or | R | 000000 |
100101 (37) |
| nor | R | 000000 |
100111 (39) |
| slt | R | 000000 |
101010 (42) |
| sll | R | 000000 |
000000 (0) |
| srl | R | 000000 |
000010 (2) |
| sra | R | 000000 |
000011 (3) |
| jr | R | 000000 |
001000 (8) |
| addi | I | 001000 (8) |
— |
| slti | I | 001010 (10) |
— |
| andi | I | 001100 (12) |
— |
| ori | I | 001101 (13) |
— |
| lui | I | 001111 (15) |
— |
| lw | I | 100011 (35) |
— |
| sw | I | 101011 (43) |
— |
| beq | I | 000100 (4) |
— |
| bne | I | 000101 (5) |
— |
| j | J | 000010 (2) |
— |
| jal | J | 000011 (3) |
— |
2. R-Type Instructions
Format: op(6) | rs(5) | rt(5) | rd(5) | shamt(5) | funct(6)
- op is always
000000for standard R-type instructions. - rs, rt = source registers; rd = destination register.
- shamt (shift amount) is only used by shift instructions; otherwise
00000. - funct selects the operation.
R-1: add $t2, $t0, $t1
Meaning: $t2 = $t0 + $t1 — integer addition (signed).
| Field | Value | Binary |
|---|---|---|
| op | SPECIAL = 0 | 000000 |
| rs | $t0 = 8 | 01000 |
| rt | $t1 = 9 | 01001 |
| rd | $t2 = 10 | 01010 |
| shamt | 0 | 00000 |
| funct | add = 32 | 100000 |
Binary (32 bits):
000000 01000 01001 01010 00000 100000
op rs rt rd shamt funct
Grouping into nibbles:
0000 0001 0000 1001 0101 0000 0010 0000
0 1 0 9 5 0 2 0
Machine Code: 0x01095020
R-2: sub $s0, $s1, $t0
Meaning: $s0 = $s1 - $t0 — integer subtraction.
| Field | Value | Binary |
|---|---|---|
| op | SPECIAL = 0 | 000000 |
| rs | $s1 = 17 | 10001 |
| rt | $t0 = 8 | 01000 |
| rd | $s0 = 16 | 10000 |
| shamt | 0 | 00000 |
| funct | sub = 34 | 100010 |
Binary (32 bits):
000000 10001 01000 10000 00000 100010
op rs rt rd shamt funct
Grouping into nibbles:
0000 0010 0010 1000 1000 0000 0010 0010
0 2 2 8 8 0 2 2
Machine Code: 0x02288022
R-3: and $t1, $t0, $t2
Meaning: $t1 = $t0 & $t2 — bitwise AND (bit is 1 only if both source bits are 1).
| Field | Value | Binary |
|---|---|---|
| op | SPECIAL = 0 | 000000 |
| rs | $t0 = 8 | 01000 |
| rt | $t2 = 10 | 01010 |
| rd | $t1 = 9 | 01001 |
| shamt | 0 | 00000 |
| funct | and = 36 | 100100 |
Binary (32 bits):
000000 01000 01010 01001 00000 100100
op rs rt rd shamt funct
Grouping into nibbles:
0000 0001 0000 1010 0100 1000 0010 0100
0 1 0 A 4 8 2 4
Machine Code: 0x010A4824
R-4: or $s1, $t0, $t1
Meaning: $s1 = $t0 | $t1 — bitwise OR (bit is 1 if either source bit is 1).
| Field | Value | Binary |
|---|---|---|
| op | SPECIAL = 0 | 000000 |
| rs | $t0 = 8 | 01000 |
| rt | $t1 = 9 | 01001 |
| rd | $s1 = 17 | 10001 |
| shamt | 0 | 00000 |
| funct | or = 37 | 100101 |
Binary (32 bits):
000000 01000 01001 10001 00000 100101
op rs rt rd shamt funct
Grouping into nibbles:
0000 0001 0000 1001 1000 1000 0010 0101
0 1 0 9 8 8 2 5
Machine Code: 0x01098825
R-5: nor $s0, $t0, $zero
Meaning: $s0 = ~($t0 | $zero) = ~$t0 — bitwise NOR (inverts all bits of $t0 because OR with $zero changes nothing).
Why use
norfor NOT? MIPS has no dedicated NOT instruction.nor $rd, $rs, $zerois the idiom: OR with $zero leaves the value unchanged, then NOR inverts every bit.
| Field | Value | Binary |
|---|---|---|
| op | SPECIAL = 0 | 000000 |
| rs | $t0 = 8 | 01000 |
| rt | $zero = 0 | 00000 |
| rd | $s0 = 16 | 10000 |
| shamt | 0 | 00000 |
| funct | nor = 39 | 100111 |
Binary (32 bits):
000000 01000 00000 10000 00000 100111
op rs rt rd shamt funct
Grouping into nibbles:
0000 0001 0000 0000 1000 0000 0010 0111
0 1 0 0 8 0 2 7
Machine Code: 0x01008027
R-6: slt $t0, $s0, $s1
Meaning: $t0 = ($s0 < $s1) ? 1 : 0 — set on less than. Useful for comparisons before a conditional branch.
| Field | Value | Binary |
|---|---|---|
| op | SPECIAL = 0 | 000000 |
| rs | $s0 = 16 | 10000 |
| rt | $s1 = 17 | 10001 |
| rd | $t0 = 8 | 01000 |
| shamt | 0 | 00000 |
| funct | slt = 42 | 101010 |
Binary (32 bits):
000000 10000 10001 01000 00000 101010
op rs rt rd shamt funct
Grouping into nibbles:
0000 0010 0001 0001 0100 0000 0010 1010
0 2 1 1 4 0 2 A
Machine Code: 0x0211402A
R-7: sll $t1, $t0, 4
Meaning: $t1 = $t0 << 4 — shift $t0 left by 4 bit positions (equivalent to multiplying by 2⁴ = 16).
Key difference from arithmetic instructions: For shift instructions, rs is unused (always 00000). The source register is rt, not rs. The shift amount goes in the shamt field.
op(6) | rs(5) | rt(5) | rd(5) | shamt(5) | funct(6)
000000 00000 01000 01001 00100 000000
| Field | Value | Binary |
|--------|-------------------|---------|
| op | SPECIAL = 0 | 000000 |
| rs | unused = 0 | 00000 |
| rt | $t0 = 8 (source) | 01000 |
| rd | $t1 = 9 (dest) | 01001 |
| shamt | 4 | 00100 |
| funct | sll = 0 | 000000 |
Binary (32 bits):
000000 00000 01000 01001 00100 000000
op rs rt rd shamt funct
Grouping into nibbles:
0000 0000 0000 1000 0100 1001 0000 0000
0 0 0 8 4 9 0 0
Verify:
(rt << 16) | (rd << 11) | (shamt << 6) | funct=(8 << 16) | (9 << 11) | (4 << 6) | 0=0x80000 | 0x4800 | 0x100=0x84900→0x00084900.
Machine Code: 0x00084900
R-8: srl $t2, $t1, 2
Meaning: $t2 = $t1 >> 2 — logical right shift by 2 (unsigned divide by 4; zeros fill from the left).
| Field | Value | Binary |
|---|---|---|
| op | SPECIAL = 0 | 000000 |
| rs | unused = 0 | 00000 |
| rt | $t1 = 9 (source) | 01001 |
| rd | $t2 = 10 (dest) | 01010 |
| shamt | 2 | 00010 |
| funct | srl = 2 | 000010 |
Binary (32 bits):
000000 00000 01001 01010 00010 000010
op rs rt rd shamt funct
Grouping into nibbles:
0000 0000 0000 1001 0101 0000 1000 0010
0 0 0 9 5 0 8 2
Machine Code: 0x00095082
R-9: sra $s0, $t0, 3
Meaning: $s0 = $t0 >> 3 — arithmetic right shift by 3 (signed divide by 8; the sign bit is copied into vacated positions, preserving the sign for negative numbers).
srl vs sra:
srlfills left bits with 0 (correct for unsigned).srafills left bits with the original sign bit (correct for signed/two's-complement integers).
| Field | Value | Binary |
|---|---|---|
| op | SPECIAL = 0 | 000000 |
| rs | unused = 0 | 00000 |
| rt | $t0 = 8 (source) | 01000 |
| rd | $s0 = 16 (dest) | 10000 |
| shamt | 3 | 00011 |
| funct | sra = 3 | 000011 |
Binary (32 bits):
000000 00000 01000 10000 00011 000011
op rs rt rd shamt funct
Grouping into nibbles:
0000 0000 0000 1000 1000 0000 1100 0011
0 0 0 8 8 0 C 3
Machine Code: 0x000880C3
R-10: jr $ra
Meaning: Jump to the address stored in $ra. Used to return from a function (the caller saved the return address in $ra before the call).
| Field | Value | Binary |
|---|---|---|
| op | SPECIAL = 0 | 000000 |
| rs | $ra = 31 | 11111 |
| rt | unused = 0 | 00000 |
| rd | unused = 0 | 00000 |
| shamt | 0 | 00000 |
| funct | jr = 8 | 001000 |
Binary (32 bits):
000000 11111 00000 00000 00000 001000
op rs rt rd shamt funct
Grouping into nibbles:
0000 0011 1110 0000 0000 0000 0000 1000
0 3 E 0 0 0 0 8
Machine Code: 0x03E00008
3. I-Type Instructions
Format: op(6) | rs(5) | rt(5) | immediate(16)
- rs = source (base) register.
- rt = destination (for arithmetic/load) or second source (for store/branch).
- immediate = 16-bit signed constant (sign-extended to 32 bits at execution time).
I-1: addi $t1, $t0, 100
Meaning: $t1 = $t0 + 100 — add a positive immediate.
| Field | Value | Binary |
|---|---|---|
| op | addi = 8 | 001000 |
| rs | $t0 = 8 | 01000 |
| rt | $t1 = 9 | 01001 |
| immediate | 100 = 0x0064 | 0000000001100100 |
Binary (32 bits):
001000 01000 01001 0000000001100100
op rs rt immediate
Grouping into nibbles:
0010 0001 0000 1001 0000 0000 0110 0100
2 1 0 9 0 0 6 4
Machine Code: 0x21090064
I-2: addi $t0, $t0, -16
Meaning: $t0 = $t0 + (-16) = $t0 - 16 — subtract 16 using a negative immediate.
MIPS has no "subtract immediate" instruction. Subtraction of a constant is done with
addiusing a negative 16-bit two's-complement value.
Converting -16 to 16-bit two's complement:
+16 = 0000 0000 0001 0000
Flip = 1111 1111 1110 1111
+1 = 1111 1111 1111 0000 = 0xFFF0
| Field | Value | Binary |
|---|---|---|
| op | addi = 8 | 001000 |
| rs | $t0 = 8 | 01000 |
| rt | $t0 = 8 | 01000 |
| immediate | -16 = 0xFFF0 | 1111111111110000 |
Binary (32 bits):
001000 01000 01000 1111111111110000
op rs rt immediate (-16)
Grouping into nibbles:
0010 0001 0000 1000 1111 1111 1111 0000
2 1 0 8 F F F 0
Machine Code: 0x2108FFF0
I-3: slti $s0, $t0, 10
Meaning: $s0 = ($t0 < 10) ? 1 : 0 — set $s0 to 1 if $t0 is less than the signed immediate 10; otherwise 0.
| Field | Value | Binary |
|---|---|---|
| op | slti = 10 | 001010 |
| rs | $t0 = 8 | 01000 |
| rt | $s0 = 16 | 10000 |
| immediate | 10 = 0x000A | 0000000000001010 |
Binary (32 bits):
001010 01000 10000 0000000000001010
op rs rt immediate
Grouping into nibbles:
0010 1001 0001 0000 0000 0000 0000 1010
2 9 1 0 0 0 0 A
Machine Code: 0x2910000A
I-4: andi $t1, $t0, 0x00FF
Meaning: $t1 = $t0 & 0x00FF — keep only the lowest 8 bits of $t0, clearing the upper bits. Useful for masking.
andi vs addi immediate handling:
addisign-extends the immediate.andiandorizero-extend the 16-bit immediate before operating, soandi $rd, $rs, 0xFFFFclears the upper 16 bits (not a sign-extension issue).
| Field | Value | Binary |
|---|---|---|
| op | andi = 12 | 001100 |
| rs | $t0 = 8 | 01000 |
| rt | $t1 = 9 | 01001 |
| immediate | 0x00FF | 0000000011111111 |
Binary (32 bits):
001100 01000 01001 0000000011111111
op rs rt immediate
Grouping into nibbles:
0011 0001 0000 1001 0000 0000 1111 1111
3 1 0 9 0 0 F F
Machine Code: 0x310900FF
I-5: ori $t1, $t0, 0x000F
Meaning: $t1 = $t0 | 0x000F — set the lowest 4 bits of $t0 to 1, leaving all other bits unchanged.
| Field | Value | Binary |
|---|---|---|
| op | ori = 13 | 001101 |
| rs | $t0 = 8 | 01000 |
| rt | $t1 = 9 | 01001 |
| immediate | 0x000F | 0000000000001111 |
Binary (32 bits):
001101 01000 01001 0000000000001111
op rs rt immediate
Grouping into nibbles:
0011 0101 0000 1001 0000 0000 0000 1111
3 5 0 9 0 0 0 F
Machine Code: 0x3509000F
I-6: lui $t0, 0x1234
Meaning: Load upper immediate — places 0x1234 into the upper 16 bits of $t0 and sets the lower 16 bits to 0x0000. Result: $t0 = 0x12340000.
Why
luiexists: MIPS I-type instructions can only hold a 16-bit immediate. To load a full 32-bit constant (e.g.0x12345678), use:lui $t0, 0x1234followed byori $t0, $t0, 0x5678. The assembler pseudo-instructionli $t0, 0x12345678expands to exactly these two instructions.
| Field | Value | Binary |
|---|---|---|
| op | lui = 15 | 001111 |
| rs | $zero = 0 | 00000 |
| rt | $t0 = 8 | 01000 |
| immediate | 0x1234 | 0001001000110100 |
Binary (32 bits):
001111 00000 01000 0001001000110100
op rs rt immediate
Grouping into nibbles:
0011 1100 0000 1000 0001 0010 0011 0100
3 C 0 8 1 2 3 4
Machine Code: 0x3C081234
I-7: lw $t1, 8($t0)
Meaning: $t1 = Memory[$t0 + 8] — load a 32-bit word from memory at address $t0 + 8 into $t1.
- rs = base address register ($t0).
- rt = destination register ($t1).
- offset = signed 16-bit displacement added to rs.
| Field | Value | Binary |
|---|---|---|
| op | lw = 35 | 100011 |
| rs | $t0 = 8 | 01000 |
| rt | $t1 = 9 | 01001 |
| offset | 8 = 0x0008 | 0000000000001000 |
Binary (32 bits):
100011 01000 01001 0000000000001000
lw rs rt offset
Grouping into nibbles:
1000 1101 0000 1001 0000 0000 0000 1000
8 D 0 9 0 0 0 8
Machine Code: 0x8D090008
I-8: sw $t2, 12($t0)
Meaning: Memory[$t0 + 12] = $t2 — store the word in $t2 to memory at address $t0 + 12.
Note on sw field order: Unlike
lw, the register being stored (rt = $t2) is the second register in the assembly syntax but occupies the rt field in the encoding (same position aslw). The base address register (rs = $t0) is the one with the offset.
| Field | Value | Binary |
|---|---|---|
| op | sw = 43 | 101011 |
| rs | $t0 = 8 | 01000 |
| rt | $t2 = 10 | 01010 |
| offset | 12 = 0x000C | 0000000000001100 |
Binary (32 bits):
101011 01000 01010 0000000000001100
sw rs rt offset
Grouping into nibbles:
1010 1101 0000 1010 0000 0000 0000 1100
A D 0 A 0 0 0 C
Machine Code: 0xAD0A000C
I-9: beq $t0, $t1, 4
Meaning: If $t0 == $t1, branch forward by 4 instructions (branch offset = 4 words = 16 bytes).
How the branch target is computed:
Target address = (PC + 4) + (offset × 4)
= (PC + 4) + (4 × 4)
= (PC + 4) + 16
The offset in the instruction is counted in words (4 bytes each), not bytes. The CPU first increments PC to PC+4, then adds
offset × 4.
| Field | Value | Binary |
|---|---|---|
| op | beq = 4 | 000100 |
| rs | $t0 = 8 | 01000 |
| rt | $t1 = 9 | 01001 |
| offset | 4 (words) | 0000000000000100 |
Binary (32 bits):
000100 01000 01001 0000000000000100
beq rs rt offset
Grouping into nibbles:
0001 0001 0000 1001 0000 0000 0000 0100
1 1 0 9 0 0 0 4
Machine Code: 0x11090004
I-10: bne $t0, $zero, -8
Meaning: If $t0 ≠ 0, branch backward by 8 instructions (offset = -8 words = -32 bytes). Used to loop back.
Converting -8 to 16-bit two's complement:
+8 = 0000 0000 0000 1000
Flip = 1111 1111 1111 0111
+1 = 1111 1111 1111 1000 = 0xFFF8
Target address: (PC + 4) + (-8 × 4) = PC + 4 - 32 = PC - 28
| Field | Value | Binary |
|---|---|---|
| op | bne = 5 | 000101 |
| rs | $t0 = 8 | 01000 |
| rt | $zero = 0 | 00000 |
| offset | -8 = 0xFFF8 | 1111111111111000 |
Binary (32 bits):
000101 01000 00000 1111111111111000
bne rs rt offset (-8 words)
Grouping into nibbles:
0001 0101 0000 0000 1111 1111 1111 1000
1 5 0 0 F F F 8
Machine Code: 0x1500FFF8
4. J-Type Instructions
Format: op(6) | target(26)
The 26-bit target field stores a word address (the byte address divided by 4). The full 32-bit jump target is reconstructed as:
Jump target = { PC[31:28], target[25:0], 2'b00 }
That is: take the top 4 bits from PC+4, concatenate the 26-bit field, then append 2 zero bits (because all instructions are word-aligned). This gives a 32-bit byte address.
To encode: 26-bit field = (target byte address) >> 2, then take only the lower 26 bits.
J-1: j 0x00400020
Meaning: Unconditional jump to address 0x00400020.
Encoding the target:
0x00400020 ÷ 4 = 0x00100008
Binary of 0x00100008:
0000 0000 0001 0000 0000 0000 0000 1000
Lower 26 bits: 00 0001 0000 0000 0000 0000 1000
= 0b00000100000000000000001000
| Field | Value | Binary |
|---|---|---|
| op | j = 2 | 000010 |
| target | 0x00100008 (lower 26 bits) | 00000100000000000000001000 |
Binary (32 bits):
000010 00000100000000000000001000
op 26-bit target
Grouping into nibbles:
0000 1000 0001 0000 0000 0000 0000 1000
0 8 1 0 0 0 0 8
Machine Code: 0x08100008
Verification: { 0x0, 0x00100008, 0b00 } → 0x00400020 ✓
J-2: jal 0x00401000
Meaning: Jump and link — jump to 0x00401000 and save the return address (PC + 4) into $ra. Used to call a function.
jal vs j:
jis a plain jump with no return mechanism.jaladditionally writesPC + 4into$raso the callee can return withjr $ra.
Encoding the target:
0x00401000 ÷ 4 = 0x00100400
Binary of 0x00100400:
0000 0000 0001 0000 0000 0100 0000 0000
Lower 26 bits: 00 0001 0000 0000 0001 0000 0000
= 0b00000100000000000100000000
| Field | Value | Binary |
|---|---|---|
| op | jal = 3 | 000011 |
| target | 0x00100400 (lower 26 bits) | 00000100000000000100000000 |
Binary (32 bits):
000011 00000100000000000100000000
op 26-bit target
Grouping into nibbles:
0000 1100 0001 0000 0000 0100 0000 0000
0 C 1 0 0 4 0 0
Machine Code: 0x0C100400
5. Complete Program Example
The following MIPS program finds the larger of two integers stored in $s0 and $s1, stores the result in $s2, then returns. It uses all three instruction types.
# Find max($s0, $s1), store in $s2
# Assumes: $s0 and $s1 hold the two values
# $ra holds return address (caller used jal)
find_max:
slt $t0, $s0, $s1 # $t0 = 1 if $s0 < $s1
bne $t0, $zero, use_s1 # if ($s0 < $s1), jump to use_s1
add $s2, $s0, $zero # $s2 = $s0 (s0 >= s1, so max = s0)
jr $ra # return
use_s1:
add $s2, $s1, $zero # $s2 = $s1
jr $ra # return
# Caller (at address 0x00400000):
main:
addi $s0, $zero, 42 # $s0 = 42
addi $s1, $zero, 17 # $s1 = 17
jal find_max # call find_max; $ra = PC + 4
sw $s2, 0($sp) # store result to stack top
lw $s2, 0($sp) # reload result (illustrative round-trip)
j end # jump to end
end:
jr $ra
Encoding each instruction
Assume find_max starts at 0x00400018 and end is at 0x00400038.
slt $t0, $s0, $s1 — R-type
000000 10000 10001 01000 00000 101010
op rs rt rd shamt funct
= 0000 0010 0001 0001 0100 0000 0010 1010
= 0x0211402A
bne $t0, $zero, 2 — I-type (skip 2 instructions forward if branch taken)
000101 01000 00000 0000000000000010
bne rs rt offset (+2)
= 0001 0101 0000 0000 0000 0000 0000 0010
= 0x15000002
add $s2, $s0, $zero — R-type
000000 10000 00000 10010 00000 100000
op rs rt rd shamt funct
= 0000 0010 0000 0000 1001 0000 0010 0000
= 0x02009020
jr $ra — R-type (× 2 occurrences, same encoding)
000000 11111 00000 00000 00000 001000
= 0x03E00008
add $s2, $s1, $zero — R-type
000000 10001 00000 10010 00000 100000
op rs rt rd shamt funct
= 0000 0010 0010 0000 1001 0000 0010 0000
= 0x02209020
addi $s0, $zero, 42 — I-type
001000 00000 10000 0000000000101010
op rs rt immediate
= 0010 0000 0001 0000 0000 0000 0010 1010
= 0x2010002A
addi $s1, $zero, 17 — I-type
001000 00000 10001 0000000000010001
op rs rt immediate
= 0010 0000 0001 0001 0000 0000 0001 0001
= 0x20110011
jal 0x00400018 — J-type (target = find_max)
0x00400018 >> 2 = 0x00100006
000011 00000100000000000000000110
= 0000 1100 0001 0000 0000 0000 0000 0110
= 0x0C100006
sw $s2, 0($sp) — I-type
101011 11101 10010 0000000000000000
sw $sp $s2 offset 0
= 1010 1111 1010 0001 0000 0000 0000 0000 -- wait, $sp=29=11101, $s2=18=10010
= 1010 1111 1011 0010 0000 0000 0000 0000
= 0xAFB20000
lw $s2, 0($sp) — I-type
100011 11101 10010 0000000000000000
lw $sp $s2 offset 0
= 1000 1111 1011 0010 0000 0000 0000 0000 -- $sp=29=11101 → op|rs: 100011_11101
= 0x8FB20000
j end — J-type (target = 0x00400038)
0x00400038 >> 2 = 0x0010000E
000010 00000100000000000000001110
= 0000 1000 0001 0000 0000 0000 0000 1110
= 0x0810000E
Program encoding summary
| Address | Assembly | Type | Machine Code |
|---|---|---|---|
0x00400018 |
slt $t0, $s0, $s1 |
R | 0x0211402A |
0x0040001C |
bne $t0, $zero, 2 |
I | 0x15000002 |
0x00400020 |
add $s2, $s0, $zero |
R | 0x02009020 |
0x00400024 |
jr $ra |
R | 0x03E00008 |
0x00400028 |
add $s2, $s1, $zero |
R | 0x02209020 |
0x0040002C |
jr $ra |
R | 0x03E00008 |
0x00400000 |
addi $s0, $zero, 42 |
I | 0x2010002A |
0x00400004 |
addi $s1, $zero, 17 |
I | 0x20110011 |
0x00400008 |
jal 0x00400018 |
J | 0x0C100006 |
0x0040000C |
sw $s2, 0($sp) |
I | 0xAFB20000 |
0x00400010 |
lw $s2, 0($sp) |
I | 0x8FB20000 |
0x00400014 |
j 0x00400038 |
J | 0x0810000E |
0x00400038 |
jr $ra |
R | 0x03E00008 |
6. Full Summary Table
| # | Instruction | Type | op | Binary (32 bits) | Hex |
|---|---|---|---|---|---|
| R-1 | add $t2, $t0, $t1 |
R | 000000 |
0000 0001 0000 1001 0101 0000 0010 0000 |
0x01095020 |
| R-2 | sub $s0, $s1, $t0 |
R | 000000 |
0000 0010 0010 1000 1000 0000 0010 0010 |
0x02288022 |
| R-3 | and $t1, $t0, $t2 |
R | 000000 |
0000 0001 0000 1010 0100 1000 0010 0100 |
0x010A4824 |
| R-4 | or $s1, $t0, $t1 |
R | 000000 |
0000 0001 0000 1001 1000 1000 0010 0101 |
0x01098825 |
| R-5 | nor $s0, $t0, $zero |
R | 000000 |
0000 0001 0000 0000 1000 0000 0010 0111 |
0x01008027 |
| R-6 | slt $t0, $s0, $s1 |
R | 000000 |
0000 0010 0001 0001 0100 0000 0010 1010 |
0x0211402A |
| R-7 | sll $t1, $t0, 4 |
R | 000000 |
0000 0000 0000 1000 0100 1001 0000 0000 |
0x00084900 |
| R-8 | srl $t2, $t1, 2 |
R | 000000 |
0000 0000 0000 1001 0101 0000 1000 0010 |
0x00095082 |
| R-9 | sra $s0, $t0, 3 |
R | 000000 |
0000 0000 0000 1000 1000 0000 1100 0011 |
0x000880C3 |
| R-10 | jr $ra |
R | 000000 |
0000 0011 1110 0000 0000 0000 0000 1000 |
0x03E00008 |
| I-1 | addi $t1, $t0, 100 |
I | 001000 |
0010 0001 0000 1001 0000 0000 0110 0100 |
0x21090064 |
| I-2 | addi $t0, $t0, -16 |
I | 001000 |
0010 0001 0000 1000 1111 1111 1111 0000 |
0x2108FFF0 |
| I-3 | slti $s0, $t0, 10 |
I | 001010 |
0010 1001 0001 0000 0000 0000 0000 1010 |
0x2910000A |
| I-4 | andi $t1, $t0, 0x00FF |
I | 001100 |
0011 0001 0000 1001 0000 0000 1111 1111 |
0x310900FF |
| I-5 | ori $t1, $t0, 0x000F |
I | 001101 |
0011 0101 0000 1001 0000 0000 0000 1111 |
0x3509000F |
| I-6 | lui $t0, 0x1234 |
I | 001111 |
0011 1100 0000 1000 0001 0010 0011 0100 |
0x3C081234 |
| I-7 | lw $t1, 8($t0) |
I | 100011 |
1000 1101 0000 1001 0000 0000 0000 1000 |
0x8D090008 |
| I-8 | sw $t2, 12($t0) |
I | 101011 |
1010 1101 0000 1010 0000 0000 0000 1100 |
0xAD0A000C |
| I-9 | beq $t0, $t1, 4 |
I | 000100 |
0001 0001 0000 1001 0000 0000 0000 0100 |
0x11090004 |
| I-10 | bne $t0, $zero, -8 |
I | 000101 |
0001 0101 0000 0000 1111 1111 1111 1000 |
0x1500FFF8 |
| J-1 | j 0x00400020 |
J | 000010 |
0000 1000 0001 0000 0000 0000 0000 1000 |
0x08100008 |
| J-2 | jal 0x00401000 |
J | 000011 |
0000 1100 0001 0000 0000 0100 0000 0000 |
0x0C100400 |
7. Encoding Tips & Checklist
Step-by-step encoding procedure
1. Identify the instruction type: R, I, or J
2. Look up the opcode (and funct for R-type)
3. Convert each register to its 5-bit number
4. Convert the immediate/offset/target to binary
- Positive integer: standard binary
- Negative integer: two's complement (flip bits + add 1)
- Branch offset: in WORDS, not bytes (÷ 4)
- Jump target: byte address ÷ 4, lower 26 bits
5. Concatenate all fields in order
6. Group 32 bits into 8 nibbles → convert each to hex
Common mistakes to avoid
| Mistake | What to do instead |
|---|---|
| Using byte offset for branch | Branch offset is in words (divide by 4) |
| Using byte address for J-type | Shift right by 2 bits (divide by 4) |
Confusing rs and rt for sw |
For sw, rs = base, rt = data register |
| Using funct for I-type | I-type has no funct field |
| Putting rd in I-type | I-type has no rd; the destination is rt |
| Forgetting rs=0 for shift | sll/srl/sra: rs is always 00000 |
| Sign-extending andi/ori | andi and ori zero-extend their immediate |
Negative immediate quick reference
| Decimal | 16-bit hex | 16-bit binary |
|---|---|---|
| -1 | 0xFFFF |
1111 1111 1111 1111 |
| -4 | 0xFFFC |
1111 1111 1111 1100 |
| -8 | 0xFFF8 |
1111 1111 1111 1000 |
| -16 | 0xFFF0 |
1111 1111 1111 0000 |
| -32 | 0xFFE0 |
1111 1111 1110 0000 |
| -64 | 0xFFC0 |
1111 1111 1100 0000 |
| -128 | 0xFF80 |
1111 1111 1000 0000 |
| -256 | 0xFF00 |
1111 1111 0000 0000 |
Binary-to-hex nibble map
0000 = 0 0100 = 4 1000 = 8 1100 = C
0001 = 1 0101 = 5 1001 = 9 1101 = D
0010 = 2 0110 = 6 1010 = A 1110 = E
0011 = 3 0111 = 7 1011 = B 1111 = F