Loading header...

Opcode Tables - The Bit Dictionary Inside a CPU

An assembler mnemonic is written for humans. The CPU executes bits. An opcode table is the dictionary between those two worlds.

When you write ADD R5, R3, the assembler does not send the letters A-D-D to the CPU. It looks up the instruction format, places register numbers and immediate values into fixed bit fields, and emits a binary instruction word. The decoder inside the CPU is built to recognize those bit patterns and assert the matching control signals.

Learning Objectives

By the end of this lesson, you should be able to:

  • read an opcode table as a fixed bit-field layout;
  • distinguish opcode bits from operand fields;
  • encode simple AVR and ARM Thumb instructions by hand;
  • explain why register fields may be split or restricted;
  • connect instruction encoding to decoder hardware.

Why Instruction Tables Exist

Every instruction word has limited space. For a 16-bit instruction, the architecture must divide those 16 bits among:

  • fixed opcode bits that identify the instruction family;
  • register fields;
  • immediate fields;
  • branch offsets;
  • condition or mode bits.
flowchart LR ASM["Assembly mnemonic"] --> LOOKUP["Opcode table lookup"] LOOKUP --> FIELDS["Fill fixed fields"] FIELDS --> WORD["Instruction word"] WORD --> DEC["CPU decoder"] DEC --> CTRL["Control signals"]

The exact bit positions are architecture-specific. AVR, ARM Thumb, RISC-V compressed instructions, and 8051 all make different trade-offs.

Reading Bit-Field Notation

Opcode tables usually number bits from most significant to least significant.

bit:  15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
word:  1  1  1  0  K  K  K  K  d  d  d  d  K  K  K  K

Common symbols:

Symbol Meaning
0, 1 fixed opcode bit
d destination register field
r, m, n source register fields
K, i immediate constant bits
k branch or address offset bits

If a field is split, the assembler still treats it as one value. It simply places different bits of that value into different locations.

AVR Example: ADD Rd, Rr

Classic AVR ADD has this format:

0000 11rd dddd rrrr
Bits Field Meaning
15..10 000011 fixed opcode for ADD
9 r bit 4 of source register Rr
8..4 ddddd destination register Rd
3..0 rrrr bits 3..0 of source register Rr

Worked encoding: ADD R5, R3

Rd = 5  = 00101
Rr = 3  = 00011

format: 0000 11 r ddddd rrrr
        0000 11 0 00101 0011
binary: 0000 1100 0101 0011
hex:    0x0C53

The source register field is split because AVR's instruction map was packed tightly. Split fields are common in real instruction sets.

AVR Example: LDI Rd, K

LDI loads an 8-bit immediate into registers R16 through R31.

1110 KKKK dddd KKKK
Bits Field Meaning
15..12 1110 fixed opcode for LDI
11..8 upper K nibble immediate bits 7..4
7..4 dddd destination register minus 16
3..0 lower K nibble immediate bits 3..0

Worked encoding: LDI R16, 0x42

K = 0x42 = 0100 0010
R16 maps to dddd = 0000

format: 1110 KKKK dddd KKKK
binary: 1110 0100 0000 0010
hex:    0xE402

Important restriction: LDI R5, 0x42 is invalid on classic AVR because the dddd field cannot name R0 through R15.

AVR Example: RJMP k

RJMP uses a signed 12-bit word offset:

1100 kkkk kkkk kkkk

The target is computed relative to the next instruction:

target word address = PC + 1 + sign_extend(k)

The 12-bit signed range is:

-2048 to +2047 words

Because AVR program memory is word-addressed for instruction fetch, this is about -4096 to +4094 bytes of reach for 16-bit instruction words. Always check the exact wording in the device manual and assembler listing.

ARM Thumb Example: ADDS Rd, Rn, Rm

A common 16-bit Thumb register add form is:

0001 100m mmnn nddd
Bits Field Meaning
15..9 0001100 fixed opcode for register ADDS
8..6 mmm second source register Rm, low registers only
5..3 nnn first source register Rn, low registers only
2..0 ddd destination register Rd, low registers only

Worked encoding: ADDS R0, R1, R2

Rm = R2 = 010
Rn = R1 = 001
Rd = R0 = 000

format: 0001 100m mmnn nddd
binary: 0001 1000 1000 1000
hex:    0x1888

The 3-bit register fields can name only R0 through R7. Thumb has other encodings for high registers, but they use different bit layouts.

ARM Thumb Example: MOVS Rd, #imm8

Thumb move-immediate format:

0010 0ddd iiii iiii

Worked encoding: MOVS R3, #25

Rd = R3 = 011
imm8 = 25 = 0x19 = 0001 1001

format: 0010 0ddd iiii iiii
binary: 0010 0011 0001 1001
hex:    0x2319

The opcode table tells the assembler exactly where the register number and immediate byte go. The decoder later checks the fixed top bits to select the move-immediate datapath.

Side-by-Side Trade-Offs

Instruction Width Fixed opcode bits Operand fields Main trade-off
AVR ADD Rd,Rr 16 6 two 5-bit registers, one split full 32-register access
AVR LDI Rd,K 16 4 4-bit high-register field, 8-bit immediate immediate fits, register range limited
AVR RJMP k 16 4 signed 12-bit offset good relative reach
Thumb ADDS Rd,Rn,Rm 16 7 three 3-bit low-register fields compact but low registers only
Thumb MOVS Rd,#imm8 16 5 3-bit register, 8-bit immediate compact literal load

There is no universal "best" layout. More bits for opcodes mean more instruction variants. More bits for operands mean larger register numbers, wider immediates, or farther branches.

How the Decoder Uses the Table

The decoder does not search a software table at runtime. The opcode table describes hardware comparisons and routing.

flowchart TD WORD["Fetched instruction word"] --> TOP["Check fixed opcode bits"] TOP --> ADD["ADD pattern: enable ALU add"] TOP --> LDI["LDI pattern: route immediate"] TOP --> BR["RJMP pattern: route PC adder"] TOP --> BAD["No legal match: illegal instruction path"] ADD --> RF["Read register fields"] LDI --> IMM["Extract immediate field"] BR --> OFF["Sign extend offset"]

Modern decoders can be pipelined, table-driven in microcode, or split into multiple decode stages, but the basic idea remains: fixed bit patterns choose control signals.

Practical Checks

  • Verify bit numbering before hand-encoding.
  • Check whether immediates are signed, unsigned, shifted, scaled, or split.
  • Check whether register fields name all registers or only a subset.
  • Confirm whether branch offsets are measured in bytes, halfwords, or words.
  • Use the assembler listing file to compare your hand encoding with tool output.
  • Remember endianness affects how bytes are stored in memory, not the logical bit layout shown in the opcode table.

Common Mistakes

  • Treating a split field as two separate values.
  • Forgetting an offset is relative to PC + 1 or another architecture-specific base.
  • Encoding an immediate that is too large for the field.
  • Using a high register in a low-register-only Thumb instruction.
  • Confusing instruction-word bit order with byte order in memory.
  • Assuming two architectures encode similar mnemonics similarly.

Summary

Opcode tables are precise maps from assembly syntax to instruction bits. Fixed opcode bits identify the instruction; operand fields carry register numbers, immediates, and offsets. Reading these tables explains assembler errors, register restrictions, branch ranges, instruction size, and the decoder hardware that turns bits into control signals.

Further Reading

  • Microchip, AVR Instruction Set Manual, instruction encodings and status effects.
  • Arm, Thumb Instruction Set Quick Reference Card and Cortex-M architecture documentation.
  • Patterson and Hennessy, Computer Organization and Design, instruction formats and datapath control.
  • GNU Binutils documentation, assembler listing files and disassembly tools.

Mind Map

mindmap root((Opcode Tables)) Core concept Mnemonic to bits Fixed opcode fields Operand fields Decoder control AVR examples ADD format 000011rdddddrrrr LDI uses R16 to R31 RJMP target equals PC plus 1 plus k k range minus 2048 to plus 2047 words Thumb examples ADDS low registers only MOVS imm8 3 bit register fields Design tradeoffs Opcode bits vs operands Immediate width Register range Branch reach Practical checks Signed offset Split fields Byte vs word offset Assembler listing Common mistakes Immediate too large Wrong PC base Endianness confusion Similar mnemonic different encoding

-> Hand-Assembly