Exercises — Instruction formats — R-type, I-type, J-type (MIPS - RISC-V)
Before we start, keep this reference strip in view — it is the ruler we measure every answer against.
Level 1 — Recognition
Goal: given a line of assembly, name its format and say why — before touching any bits.
L1.1
Classify each as R, I, or J and give the one-word reason:
add $t0,$t1,$t2 · addi $t0,$t1,5 · j 0x400000 · lw $t0,8($t1) · beq $t0,$t1,LOOP
Recall Solution L1.1
add $t0,$t1,$t2→ R-type. Reason: three registers, no constant.addi $t0,$t1,5→ I-type. Reason: a small constant (5) is present.j 0x400000→ J-type. Reason: an unconditional jump to an address, no registers.lw $t0,8($t1)→ I-type. Reason: a memory offset (8) is a 16-bit immediate.beq $t0,$t1,LOOP→ I-type. Reason: two registers plus a PC-relative offset — that offset is the immediate.
The decisive test: is there a constant/offset/label? If yes and it's small → I. If it's a huge jump target → J. If it's pure registers → R.
L1.2
For each format, state which field the decoder reads first and what it decides.
Recall Solution L1.2
All three start with the 6-bit opcode (the top 6 bits). That single field decides the format:
- opcode
= 0⇒ R-type (then read the funct field for the real operation). - opcode
= 2or3⇒ J-type. - anything else ⇒ I-type. This is why opcode is the "master key" — the Control Unit and Decoding cannot slice the other bits until it knows the rulebook.
Level 2 — Application (encode assembly → bits)
L2.1
Encode sub $s0, $s1, $s2 (R-type) as six fields, then as binary.
Recall Solution L2.1
R-type slot order in binary is opcode, rs, rt, rd, shamt, funct (sources first!). For sub $rd,$rs,$rt: rd=$s0=16, rs=$s1=17, rt=$s2=18, shamt=0, opcode=0, funct=34.
Binary: 000000 10001 10010 10000 00000 100010
As a hex word: group into 32 bits 0000 0010 0011 0010 1000 0000 0010 0010 = 0x02328022.
L2.2
Encode addi $t0, $t1, -3 (I-type). This introduces a negative immediate.
Recall Solution L2.2
addi $rt,$rs,imm → rt=$t0=8, rs=$t1=9, opcode=8, imm=-3.
The immediate is 16 bits in two's-complement (see Sign Extension and Immediates). in 16-bit two's-complement: take 0000000000000011, invert → 1111111111111100, add 1 → 1111111111111101.
Binary: 001000 01001 01000 1111111111111101
Hex: 0010 0001 0010 1000 1111 1111 1111 1101 = 0x2128FFFD.
L2.3
Encode sw $t2, -4($s3). Note how sw differs from lw in what rt means.
Recall Solution L2.3
sw $rt, offset($rs) → rs=$s3=19 (base), rt=$t2=10 (the value being stored, a source here), opcode=43, imm=-4.
in 16-bit two's-complement = 1111111111111100.
Binary: 101011 10011 01010 1111111111111100
Hex: 1010 1110 0110 1010 1111 1111 1111 1100 = 0xAE6AFFFC.
Key contrast: in lw, rt is the destination; in sw, rt is a source (the word going to memory). Same field, opposite role — the opcode tells the datapath which.
Level 3 — Analysis (decode bits → assembly)
L3.1
Decode the 32-bit word 0x012A4020 back to MIPS assembly.
Recall Solution L3.1
Expand to binary: 0x012A4020 = 0000 0001 0010 1010 0100 0000 0010 0000.
Slice by R-type widths 6/5/5/5/5/6:
- opcode =
000000= 0 ⇒ R-type, read funct. - rs =
01001= 9 =$t1 - rt =
01010= 10 =$t2 - rd =
01000= 8 =$t0 - shamt =
00000= 0 - funct =
100000= 32 ⇒addReassemble in assembly order (rd, rs, rt):add $t0, $t1, $t2.
L3.2
Decode 0x8D0A0010. (Opcode is not 0, so it is not R-type.)
Recall Solution L3.2
Binary: 1000 1101 0000 1010 0000 0000 0001 0000.
- opcode =
100011= 35 ⇒lw(I-type). - rs =
01000= 8 =$t0(base) - rt =
01010= 10 =$t2(destination) - imm =
0000000000010000= 16 Assembly:lw $t2, 16($t0).
L3.3
Decode 0x2210FFFF — watch the sign of the immediate.
Recall Solution L3.3
Binary: 0010 0010 0001 0000 1111 1111 1111 1111.
- opcode =
001000= 8 ⇒addi(I-type). - rs =
10000= 16 =$s0 - rt =
10000= 16 =$s0 - imm =
1111111111111111. Top bit is 1 ⇒ negative. Its value is (all-ones is in two's-complement). Assembly:addi $s0, $s0, -1(a decrement).
Level 4 — Synthesis (PC arithmetic, offsets, targets)
L4.1
beq $t0,$t1,LABEL sits at address . LABEL is 3 instructions after the beq. Find the immediate the assembler stores, and the byte target.
Recall Solution L4.1
The offset is measured in words from PC+4 (the instruction after the branch). "3 instructions after the beq" means the target is at . Since PC+4 , the word distance is
So the stored immediate is 2.
Check with the target formula: . ✓
L4.2
A backward branch: beq at must jump to (the top of a loop). Find the signed immediate.
Recall Solution L4.2
The immediate is . In 16-bit two's-complement: 0000000000000101, invert+1 → 1111111111111011. Backward branches always have a negative immediate — that is exactly why the field is signed.
The picture below shows both directions on a number line of addresses.
L4.3
Encode j 0x00400024 fully into a 32-bit word.
Recall Solution L4.3
Byte address 0x00400024 = 0000 0000 0100 0000 0000 0000 0010 0100.
Drop the low 2 bits (always 00 for word-aligned code) → shift right by 2. That is dividing by 4:
Only the low 26 bits of that go in the field: 00 0001 0000 0000 0000 0000 1001 = field 0x0100009.
Prepend opcode 2 = 000010:
Full binary: 000010 00000100000000000000001001.
Hex: 0000 1000 0001 0000 0000 0000 0000 1001 = 0x08100009.
Level 5 — Mastery (reason about the limits of the design)
L5.1
What is the farthest forward byte distance a single beq can reach from ? Give it in bytes and in KB.
Recall Solution L5.1
The immediate is a signed 16-bit word offset, so its maximum positive value is words. Hardware multiplies by 4: The most negative offset is words bytes backward. So the branch window is roughly ±128 KB around PC+4 — this is the "18-bit signed reach" the parent note derived ( implied bits).
L5.2
j stores a 26-bit field, appends 2 low zeros, and takes the top 4 bits from PC. Two labels are at 0x10000000 and 0x18000000. If the j executes with PC in the 0x10000000 region, which target can it reach, and which needs jr?
Recall Solution L5.2
The top 4 bits of the target come from PC. PC is in 0x1... so its top nibble is 0001.
0x10000000has top nibble0001— same region,jreaches it. ✓0x18000000also has top nibble0001(since0x1covers0x10000000–0x1FFFFFFF), so — it is also reachable! Both sit in the same 256 MB region[0x10000000, 0x1FFFFFFF]. The region size is bytes = 256 MB. Only a target whose top 4 bits differ from the current PC forces you to usejr(an R-type jump through a full 32-bit register).
L5.3
Prove numerically that a j cannot reach an address whose top nibble differs, e.g. PC region 0x0... trying to reach 0x10000000.
Recall Solution L5.3
With PC top nibble 0000, the reconstructed target is . The largest such target sets all 26 field bits to 1:
Since , the target is unreachable by j from region 0 — confirming a 256 MB ceiling per region. You would need jal/jr through a register holding the full address.
Recall Master checklist (reveal after finishing)
Bit order R-type ::: opcode, rs, rt, rd, shamt, funct
Which slot is the destination in R-type ::: rd, the third register field
Branch immediate is measured in ::: signed words, from PC+4
To get a byte offset from a branch immediate ::: multiply by 4
Negative immediate representation ::: 16-bit two's-complement, sign-extended
j reach ::: one 256 MB region (top 4 bits from PC)
When you must use jr ::: target's top 4 bits differ from PC's