Visual walkthrough — Instruction formats — R-type, I-type, J-type (MIPS - RISC-V)
Step 1 — What is a "32-bit number", really?
WHAT. A MIPS instruction is one row of 32 tiny on/off switches. Each switch is a bit — a single 0 or 1. Nothing more. The CPU has no idea what any switch means until we agree on a rulebook.
WHY start here. Because the whole problem of "instruction formats" is just: how do we carve this row of 32 switches into meaningful chunks? If we don't fix the carving in advance, the hardware cannot know whether switches 21–25 name a locker or spell part of a number.
PICTURE. Below: 32 empty boxes, numbered from bit 31 (left, most significant) down to bit 0 (right). This is the blank canvas every instruction is painted on.

Step 2 — The first question: "how many things can a chunk name?"
WHAT. Before carving anything, learn the one counting rule that governs every field width on this page: a chunk of bits can spell exactly different patterns.
WHY this tool and not another. We keep asking "how wide must this field be to name X different things?" The inverse of is the logarithm base 2, written . That's the tool: answers "how many bits do I need to name X items?" We use (not division, not ) because doubling the bits doubles the choices — a multiplicative, not additive, growth.
- — take a chunk of switches, count how many distinct 0/1 pictures it can show.
- — the reverse question: given that we must name things, how many switches?
- — the "round up" brackets (a ceiling), because you can't have a fraction of a switch.
PICTURE. A staircase: 1 bit → 2 patterns, 2 bits → 4, 3 bits → 8… and the reverse arrow reading it as "to name 32 things, climb to 5 bits."

Recall Why 5 bits for a register?
MIPS has 32 registers → . See MIPS Register File and Conventions. How many bits to name 32 registers? ::: 5, because .
Step 3 — Reserve the master key: the opcode
WHAT. Slice off the top 6 bits and call them the opcode. This chunk's only job is to answer "which rulebook (format) does the rest of this instruction follow?"
WHY 6 bits, and why first?
- First — so the decoder can read it immediately, before it knows anything else, and pick the right rulebook. (See Control Unit and Decoding.)
- 6 bits — this is a design choice giving possible opcodes. That's a comfortable menu of operations while leaving 26 bits below for everything else. Remember 6; it never changes across the three formats.
PICTURE. The 32-box strip with the leftmost 6 boxes shaded blue and labelled "opcode → which rulebook?". The remaining 26 boxes are a gray "to be decided" region.

Step 4 — R-type: carve the 26 leftover bits for "three lockers + which math"
WHAT. We want instructions like add $t0,$s1,$s2 — read two registers, combine them, write a third. That needs to name three registers and say which combining operation.
WHY these exact widths — watch them fall out.
- Three register names. Each register (from Step 2) needs bits. Three of them = bits. Call them rs, rt (the two sources) and rd (the destination).
- A shift amount. Shift instructions (
sll) can move a 32-bit word by 0–31 places → bits. Call it shamt. - "Which math?" Because opcode was spent as
0, we need a second selector. We have bits left — exactly enough for R-type operations. Call it funct.
Term by term: opcode = 0 announces "R-type"; rs, rt = the two source lockers to read; rd = the destination locker to write; shamt = how far to shift (0 for non-shift ops); funct = the real operation code. Add them: . ✓ Nothing left over, nothing missing.
PICTURE. The strip fully carved into six colored fields with widths labelled, and a checksum "6+5+5+5+5+6 = 32" underneath.

Step 5 — I-type: trade two fields for one 16-bit number
WHAT. Now we want a constant baked in — addi $t0,$s1,10, lw $t0,32($s3), beq. We keep the opcode (6) and only need two registers now, but we need room for a number.
WHY the number is 16 bits. Start from R-type and merge the three trailing fields rd + shamt + funct = bits into a single immediate field. That's where 16 comes from — it's not chosen, it's the leftover after opcode + two registers:
Term by term: rs = one source (for loads it's the base address); rt = now the destination for addi/lw (it receives the result), but a source for sw/beq; immediate = the 16-bit constant/offset. Because a constant can be negative (e.g. addi $t0,$t0,-1), the top bit of the immediate is a sign, copied leftward when used — that's Sign Extension and Immediates.
PICTURE. Two strips stacked: R-type on top, and I-type below with rd|shamt|funct shown collapsing (arrows) into one wide 16-bit "immediate" block.

Step 6 — The branch trick: how 16 bits reach far away
WHAT. beq $rs,$rt,LABEL must name a target address — but addresses are 32 bits and we only have 16 left. Deriving the escape.
WHY multiply by 4, and why relative. Two observations do all the work:
- Every instruction is 4 bytes, so every instruction address is a multiple of 4 — its low 2 bits are always
00. Storing those two zeros is a waste. So the 16 bits count words (groups of 4 bytes), not bytes. Hardware shifts left by 2 (i.e. ) to restore the bytes. - Branches jump nearby (loops, ifs), so instead of an absolute address we store a signed offset from the current spot — that's why the immediate is signed (positive = forward, negative = backward).
- — the address of the instruction after the branch (the CPU already advanced the program counter by 4).
- — the 16-bit signed word offset; negative reaches backward.
- — undo the "counted in words" saving, converting back to bytes.
Effective reach: 16 signed bits + 2 implied = 18-bit signed byte reach ( KB). See PC-relative vs Absolute Addressing.
PICTURE. A vertical column of instruction addresses (…P, P+4, P+8…). An arrow from beq at P curves to P+4 + imm×4, with a forward (green) and backward (red) example.

Step 7 — J-type: spend almost everything on an address
WHAT. j LABEL needs no registers at all — just "go there." Keep the opcode (6), give the other 26 bits to the address.
WHY 26 can still reach a 32-bit target. Same two tricks, pushed harder:
- Low 2 bits are
00(word-aligned) → append them, buying 2 bits for free. - The top 4 bits are not stored — they're copied straight from the current PC. So a jump can only move within the same 256 MB region the PC is already in.
- — the four high bits taken from the program counter (not from the instruction).
- — "glue together" (concatenate) the bit groups.
- — the 26 bits we actually stored.
- — the two always-zero low bits, appended by hardware.
Count restored bits: . ✓ Effective byte reach: bits (256 MB region).
PICTURE. A 32-bit target bar split into three colored zones — top 4 "from PC" (gray), middle 26 "stored" (blue), bottom 2 "implied 00" (orange) — with braces showing 4+26+2=32.

Step 8 — Degenerate & edge cases (never leave a gap)
WHAT / WHY. Check the corners so nothing surprises you later.
nop= all zeros.00000000...0decodes as opcode 0 (R-type), funct 0 =sll $0,$0,0— a shift of register 0 by 0. It does nothing, harmlessly. So the all-off instruction is legal.- shamt = 0 for non-shift R-types.
add,subignore shamt; it's simply zero. The field always exists even when unused. - Immediate = 0.
addi $t,$s,0is a valid copy;beq $x,$y,0targets the very next instruction (). - Negative immediate. Top bit of the 16-bit field = 1 means negative; it is sign-extended to 32 bits before use, so
-1becomes0xFFFFFFFF. Forgetting this is the classic offset bug. - Register 0.
$zero(register number 0) always reads 0 and ignores writes — even if it lands inrd. See MIPS Register File and Conventions.
PICTURE. A small table-figure: each edge case as a row (nop, shamt=0, imm=0, imm<0, $zero), with its 32-bit strip and a one-word verdict (safe / sign-extend / no-op).

The one-picture summary
All three formats sharing the same top three fields (opcode, rs, rt live in identical positions) so the same wires feed the register file — that shared alignment is the whole point of RISC regularity. Below them, the divergence: R keeps three registers + funct, I merges the tail into a 16-bit number, J merges almost everything into a 26-bit address.

Recall Feynman retelling — the whole walkthrough in plain words
Picture 32 light switches in a row. We had to agree on a rulebook or the machine couldn't tell a locker-number from a plain number. So we made the first 6 switches a code word naming which of three rulebooks we're using — that's the only field that never moves.
Then we asked one repeated question: "how many switches to name X things?" Naming one of 32 lockers takes 5 switches (because 5 switches make 32 patterns). Three lockers = 15 switches; add 5 for "how far to shift" and the 6 left over become "which math" — that's R-type, and the numbers 5-5-5-5-6 weren't chosen, they were forced.
Want a number baked in instead of a third locker? Glue the last three fields into one 16-wide slot for a constant — that's I-type, and 16 is just whatever was left over. For branches we're clever: since every instruction sits at a multiple of 4, the low two bits are always off, so we don't store them — we count in steps of 4 and measure from where we are (forward or backward), stretching 16 bits into an 18-bit reach.
Want to jump far with no lockers at all? Give 26 switches to the address, steal the low 2 (always off) for free, and borrow the top 4 from where we currently are — that's J-type, reaching one big neighborhood. Same 32 switches, three rulebooks, first 6 switches always tell you which. Every width on the page is just the answer to "how many switches do I need?" — nothing memorized.
Flashcards
Where does every field width on this page ultimately come from?
Why are register fields 5 bits?
Why 6-bit opcode read first?
Where does the 16-bit immediate width come from?
Why multiply branch/jump offsets by 4?
Branch target formula?
J-type target reconstruction?
What is the all-zero instruction?
nop, i.e. sll $0,$0,0 — does nothing.