A beginner-friendly guide to understanding opcodes: the verbs inside bytecode instructions.
Opcode is short for operation code.
It tells a virtual machine what action to perform.
instruction = opcode + operandsTable of Contents
- The Simple Idea
- Instruction vs Opcode
- Why Opcodes Exist
- A Tiny Stack Example
- Operands
- Opcodes In A VM Loop
- Opcode Design
- Readable Names vs Numeric Codes
- Where Opcode Fits In The Pipeline
- My Learning Notes
- Common Misunderstandings
The Simple Idea
An opcode tells the VM what to do.
Examples:
LOAD
STORE
ADD
CALL
RETURN
JUMPThe shortest mental model:
opcode = verb of an instructionIf bytecode is a list of instructions, opcodes are the actions inside that list.
Instruction vs Opcode
An instruction may contain more than the opcode.
The opcode says what action to perform.
The operands provide details.
Example:
LOAD 3Here:
LOADis the opcode,3is the operand.
The instruction might mean:
load the value at slot 3So:
instruction = what to do + what to useWhy Opcodes Exist
Source code is too rich for a small VM.
The compiler lowers source into bytecode instructions.
Opcodes are the vocabulary of those instructions.
Instead of making the VM understand this:
const total = price * quantityThe compiler can emit something like:
LOAD price
LOAD quantity
MUL
STORE totalThe VM does not need to know JavaScript syntax.
It only needs to know what LOAD, MUL, and STORE do.
A Tiny Stack Example
Imagine this expression:
2 + 3A stack VM might receive:
PUSH 2
PUSH 3
ADDExecution:
PUSH 2 -> stack: [2]
PUSH 3 -> stack: [2, 3]
ADD -> stack: [5]The opcode ADD means:
take the top two values
add them
push the resultThat is opcode execution in miniature.
Operands
Opcodes often need extra data.
That extra data is called an operand.
Examples:
PUSH 10
LOAD name
JUMP 24
CALL 2The opcode is the action.
The operand is the detail.
Examples:
PUSHneeds a value,LOADneeds a name or slot,JUMPneeds a target instruction,CALLmay need an argument count.
Without operands, many opcodes would be too vague.
Opcodes In A VM Loop
A VM often runs a loop like this:
read instruction
inspect opcode
execute matching behavior
move instruction pointerConceptually:
if opcode is ADD, add
if opcode is CALL, call
if opcode is RETURN, returnReal VMs also manage:
- instruction pointer,
- stack,
- call frames,
- values,
- variables,
- constants,
- jumps,
- errors,
- host functions.
But the basic idea stays the same.
The opcode selects the behavior.
Opcode Design
Designing opcodes is a language design problem.
Too few opcodes can make every instruction awkward.
Too many opcodes can make the VM hard to understand.
A good opcode set is:
- small enough to reason about,
- complete enough to express the language,
- stable enough for compiled code,
- clear enough to debug,
- simple enough to execute,
- explicit enough to test.
Every opcode is a promise.
Once the compiler emits it, the VM must support it.
Readable Names vs Numeric Codes
Humans like names:
LOAD
ADD
RETURNMachines often store numbers:
1
2
3The name is easier to discuss.
The number is easier to store and dispatch.
Both refer to the same operation.
Where Opcode Fits In The Pipeline
Opcodes sit inside bytecode:
source -> compiler -> bytecode instructions -> opcodes -> VM behaviorThe compiler chooses opcodes.
The VM obeys opcodes.
That relationship is one of the clearest contracts in a language runtime.
KitJS And Kitwork Notes
Opcodes became clear only after bytecode became real in Kitwork. Before that, bytecode felt like one vague layer. Then I saw that bytecode is made of tiny verbs.
Each opcode is a word in the VM's vocabulary: load, call, jump, return, compare, create, read, write. If the vocabulary is unclear, the compiler and VM cannot talk cleanly.
Kitwork taught me that opcodes are not only low-level details. They are design decisions. Every opcode says what kind of behavior the runtime is willing to support.
My Learning Notes
I started understanding opcodes when I stopped thinking of bytecode as one vague blob.
Bytecode is made of instructions.
Instructions are made of operations and details.
The opcode is the operation.
While learning from Kitwork's VM, this became very concrete:
LOADandSTOREcan refer to variable names through constants,- calls and method invocation need careful stack behavior,
- host values and proxy-like values affect how operations behave,
- a small opcode set still has many edge cases.
The lesson:
opcodes are the vocabulary of a VMIf the vocabulary is clear, the compiler and VM can talk clearly.
If the vocabulary is messy, every layer above it becomes harder.
Common Misunderstandings
"Opcode and bytecode are the same thing."
No. Bytecode is usually the instruction stream. Opcode is the operation part of an instruction.
"Opcode means assembly."
Not exactly. Assembly languages have operation codes, but bytecode VMs also have opcodes.
"Opcodes are always numeric."
Internally they often are. Humans usually name them so the system can be understood.
"More opcodes means a better VM."
Not always. More opcodes can make the VM harder to maintain.
"Opcodes are only about speed."
No. Opcodes are also about clarity, structure, debugging, and the compiler/VM contract.
Related Concepts
Previous: bytecode
Next: vm