In the previous chapter, we walked through the instruction cycle, following a single instruction like ADD R1, R2 as it moved through the fetch, decode, execute, and store stages. But we never stopped to examine exactly how an instruction like this is actually structured in binary form, or how the CPU knows which part of the instruction represents the operation and which parts represent the data being operated on.
This is exactly what instruction format deals with. Every instruction a CPU processes is ultimately just a fixed-length or variable-length sequence of binary digits, and instruction format defines precisely how that sequence is divided into meaningful sections, so the control unit knows exactly how to interpret it correctly.
In this tutorial, you will learn about the two core parts of every instruction, the opcode and the operand, and explore the four common instruction formats based on how many operand addresses they include: zero-address, one-address, two-address, and three-address formats, along with worked examples for each one.
An instruction format is the specific layout that defines how the bits within a single machine instruction are organized and interpreted. Just like a sentence in English follows a grammatical structure that lets you know which word is the subject and which is the verb, an instruction format tells the CPU exactly which portion of the binary instruction represents the operation to perform, and which portions represent the data or addresses involved.
Every instruction, regardless of its specific format, is generally built from two essential components: the opcode and one or more operands.
The opcode, short for operation code, specifies exactly what action the instruction is asking the CPU to perform, such as addition, subtraction, data movement, or comparison. The opcode is what the control unit examines during the decode stage of the instruction cycle to determine which operation needs to be carried out.
The operand, or operands, represent the data the instruction operates on, or the memory addresses and registers where that data can be found. Depending on the instruction format being used, an instruction might include zero, one, two, or even three separate operand fields.
Instruction: ADD R1, R2 Opcode: ADD (specifies the operation) Operand 1: R1 Operand 2: R2 This instruction tells the CPU: perform addition using the values stored in R1 and R2
A zero-address instruction contains no explicit operand fields at all, relying entirely on a special data structure called a stack to supply the values it needs to operate on. In this format, data is pushed onto the top of the stack beforehand, and instructions simply operate on whatever values currently sit at the top.
CS Engineering Gyan's simulated stack-based calculator Step 1: PUSH 10 (10 is placed on top of the stack) Step 2: PUSH 20 (20 is placed on top of the stack) Step 3: ADD (zero-address instruction, no operands listed) The ADD instruction automatically pops the top two values, 10 and 20, adds them together, and pushes the result, 30, back onto the top of the stack
Zero-address instructions are commonly associated with stack-based CPU architectures, where the stack itself implicitly supplies both operands for an operation, removing the need to specify any addresses directly within the instruction itself.
A one-address instruction includes exactly one explicit operand field, with the second operand typically assumed to be the accumulator, the special register we studied in the previous chapters that holds intermediate results.
Instruction: ADD R1 Opcode: ADD Operand: R1 This instruction implicitly means: ACC = ACC + R1 If ACC currently holds 50, and R1 holds 25, then after this instruction executes, ACC will hold 75
One-address instructions rely heavily on the accumulator acting as an implied second operand and destination, which keeps the instruction itself shorter, since only a single address needs to be explicitly written out.
A two-address instruction includes exactly two explicit operand fields. Typically, one of these operands serves as both a source of data and the destination where the result will be stored, meaning the original value in that location gets overwritten by the result.
Instruction: ADD R1, R2 Opcode: ADD Operand 1: R1 (source and destination) Operand 2: R2 (source) This instruction means: R1 = R1 + R2 If R1 currently holds 40, and R2 holds 35, then after this instruction executes, R1 will hold 75, while R2 remains unchanged at 35
Two-address instructions are extremely common in real-world CPU architectures, since they strike a practical balance between keeping instructions reasonably short while still allowing two genuinely different operands to be specified directly.
A three-address instruction includes three explicit operand fields: two source operands and a separate destination operand. Unlike the two-address format, neither of the original source values needs to be overwritten, since the result is stored in a completely separate third location.
Instruction: ADD R3, R1, R2 Opcode: ADD Operand 1: R3 (destination) Operand 2: R1 (source) Operand 3: R2 (source) This instruction means: R3 = R1 + R2 If R1 holds 40 and R2 holds 35, then after this instruction executes, R3 will hold 75, while both R1 and R2 remain completely unchanged
Three-address instructions are especially convenient for more complex calculations, since neither original operand is destroyed in the process, making it easier to reuse those same values again later without needing to reload them from memory.
| Format | Explicit Operands | Typical Example | Key Characteristic |
|---|---|---|---|
| Zero-Address | 0 | ADD | Relies entirely on a stack for both operands |
| One-Address | 1 | ADD R1 | Assumes the accumulator as the implied second operand |
| Two-Address | 2 | ADD R1, R2 | One operand serves as both source and destination |
| Three-Address | 3 | ADD R3, R1, R2 | Uses a completely separate destination operand |
Choosing between these instruction formats involves a trade-off between instruction length and flexibility. Formats with fewer explicit operands, like zero-address and one-address instructions, tend to be shorter in terms of memory space, but they depend more heavily on implicit locations like the stack or accumulator, and may require more individual instructions to accomplish more complex calculations.
Formats with more explicit operands, like the three-address format, allow more complex operations to be expressed in a single instruction, and avoid overwriting original operand values, but each instruction naturally requires more bits to represent all three addresses, increasing the overall size of the program's instructions in memory.
In addition to opcode and operand fields, real instruction formats often include additional details, such as an addressing mode field, which specifies how an operand's address should actually be interpreted, a topic we will explore in full detail in the next chapter on addressing modes.
Simplified instruction layout (conceptual, not to exact scale) | Opcode | Addressing Mode | Operand 1 | Operand 2 | Opcode: specifies the operation (e.g., ADD, SUB, MOV) Addressing Mode: specifies how to interpret the operand fields (e.g., direct address, register, immediate value) Operand fields: hold the actual addresses, register numbers, or immediate values involved
This simplified layout illustrates how real CPU instructions are typically composed of several distinct fields working together, with the opcode and addressing mode both playing an essential role in helping the control unit correctly interpret the operand fields that follow.
| Advantages | Limitations |
|---|---|
| Zero and one-address formats keep individual instructions compact and memory-efficient. | Zero and one-address formats often require more instructions to complete complex calculations. |
| Two-address formats offer a practical balance between compactness and flexibility. | Two-address formats overwrite one of the original operand values during execution. |
| Three-address formats preserve original operand values and support more complex single instructions. | Three-address formats require more bits per instruction, increasing overall program size. |
| Mistake | Correct Practice |
|---|---|
| Assuming every instruction format explicitly lists every operand it uses. | Remember that zero-address and one-address formats rely on implied locations like the stack or accumulator. |
| Confusing two-address and three-address instructions. | Remember that two-address instructions overwrite one source operand, while three-address instructions use a separate destination. |
| Assuming a shorter instruction format is always better. | Understand that shorter formats often require more individual instructions to accomplish the same overall task. |
| Overlooking the addressing mode field when analyzing instruction structure. | Remember that many real instructions also include a field specifying how their operands should be interpreted. |
Instruction format defines exactly how the opcode and operand fields within a binary instruction are organized, allowing the control unit to correctly interpret and execute every instruction during the decode stage of the instruction cycle. We explored zero-address, one-address, two-address, and three-address formats, each offering a different balance between instruction length and how explicitly their operands are specified.
Zero and one-address formats rely on implicit locations like the stack or accumulator to stay compact, while two and three-address formats explicitly specify more of their operands directly, trading some memory efficiency for greater flexibility and clarity within a single instruction. Understanding these formats makes it much easier to read and reason about how real machine instructions are actually structured.
With instruction formats covered, you are now ready to explore addressing modes in detail, where we will look closely at exactly how an operand field's value gets interpreted, whether as an immediate value, a direct address, an indirect address, or several other possible addressing techniques.