Q1Computer Architecture
Question
Q.1. Describe different instruction formats and illustrate the same with an example.
Answer
Instruction formats — three-address, two-address, one-address (accumulator), and zero-address (stack) — differ in how many explicit operand addresses are encoded, trading off instruction length against total instruction count for a given computation.
An instruction format defines the structural layout of a machine instruction, consisting of an opcode field specifying the operation, and zero or more address fields specifying the location of operands and results. Different numbers of address fields lead to fundamentally different program styles and hardware requirements.
Three-address format: specifies two source operand addresses and one destination address explicitly, e.g. ADD R1, R2, R3 performs R1 ← R2 + R3. This allows each instruction to fully and independently specify a complete operation without disturbing either source operand, minimizing the total number of instructions needed for a complex expression, at the cost of longer individual instruction words (since three full addresses must be encoded).
Two-address format: specifies two addresses, where the first typically serves as both a source operand and the destination, e.g. ADD R1, R2 performs R1 ← R1 + R2, overwriting the original value in R1. This shortens instruction length relative to three-address format but destroys one operand's original value, sometimes requiring an extra register-copy instruction beforehand if that value is still needed.
One-address (accumulator) format: specifies only a single explicit address, with the second implicit operand and the result both associated with a special accumulator register, e.g. ADD M performs AC ← AC + Memory[M]. This produces the shortest individual instructions among the register/memory-addressed formats, but requires separate LOAD and STORE instructions to move values into and out of the accumulator around each operation, increasing the total instruction count for any expression involving more than one operation.
Zero-address (stack) format: specifies no explicit operand address at all; all operations implicitly act on the top element(s) of a push-down stack, e.g. an ADD instruction pops the top two values from the stack, adds them, and pushes the result back. Programs for a stack machine are naturally expressed in postfix (Reverse Polish) notation and require explicit PUSH instructions to load operands onto the stack before each operation, yielding the shortest instructions of all formats but often the longest overall instruction sequences.
Illustrative example — evaluating X = (A + B) × C: In three-address format, this takes two instructions: ADD T, A, B (T ← A+B) followed by MUL X, T, C (X ← T×C). In two-address format: MOV R1, A then ADD R1, B then MUL R1, C then MOV X, R1 — four instructions since each two-address instruction can only update one operand in place. In one-address (accumulator) format: LOAD A, ADD B, MUL C, STORE X — four instructions, cycling every value through the single accumulator. In zero-address (stack) format, using the postfix expression A B + C ×: PUSH A, PUSH B, ADD (pops A,B, pushes A+B), PUSH C, MUL (pops sum and C, pushes result), POP X — six instructions, demonstrating that while each individual stack instruction is minimal (no address field), the total instruction count is typically the highest among the four formats for equivalent computations.
A second worked example — evaluating Y = (A − B) / (C + D × E), a more complex expression involving four operations: In three-address format, this requires four instructions, each computing one sub-expression into a temporary: MUL T1, D, E (T1 ← D×E), ADD T2, C, T1 (T2 ← C+T1), SUB T3, A, B (T3 ← A−B), and DIV Y, T3, T2 (Y ← T3/T2) — exactly one instruction per operation in the expression tree, since three-address instructions never need to reload an operand that was just computed. In one-address (accumulator) format, the same expression requires careful sequencing since the accumulator can only hold one intermediate value at a time, and any value that must be combined with a later result needs to be explicitly stored to memory and reloaded: LOAD D, MUL E (AC = D×E), ADD C (AC = C+D×E), STORE T (save denominator), LOAD A, SUB B (AC = A−B), then a division instruction combining AC with the stored T, followed by STORE Y — around eight instructions, nearly double the three-address count, illustrating how the single-accumulator bottleneck increasingly penalizes more complex, multi-operand expressions as their structure deepens.
Register-rich RISC extension of two-address format: modern RISC architectures typically extend the two-address concept into an effectively three-address, register-only format (since they have a large general-purpose register file rather than a single accumulator), combined with a strict load-store discipline where only dedicated LOAD and STORE instructions may reference memory, and all arithmetic instructions operate purely on registers. This hybrid design captures the instruction-count efficiency of three-address addressing (each arithmetic instruction fully specifies its operation without destroying an input) while keeping individual instructions short and uniformly formatted (since register numbers require far fewer bits to encode than full memory addresses), which is a major reason why the three-address, register-based instruction format dominates contemporary general-purpose processor design, from ARM and RISC-V embedded/mobile processors to the internal micro-operation format used even inside modern x86 CISC processors after their front-end instruction decoders translate complex CISC instructions into simpler RISC-like internal operations.
Illustrating with an instruction word diagram: a typical three-address register instruction might allocate, say, 6 bits for the opcode and 5 bits for each of three register fields (supporting up to 32 registers), for a total instruction width of 21 bits, comfortably fitting within a standard 32-bit fixed instruction word with room to spare for future extension (e.g., for larger immediate-value fields or additional opcode variants as the instruction set evolves). By contrast, a one-address memory-referencing instruction on the same machine might need 6 bits for the opcode plus a full 16-24 bit memory address field just to reference one operand, illustrating why accumulator-based one-address designs were historically favored when memory address buses were narrow and instruction words needed to stay compact, while today's wide instruction words and abundant registers make the three-address, register-only format the clearly preferable choice for general-purpose computing.
Conclusion: the historical progression from zero-address and one-address machines (in the earliest computers, constrained by expensive, scarce memory and minimal register hardware) through two-address designs and finally to today's dominant three-address register-based RISC format directly reflects the changing economics of computer hardware over the decades — as transistor budgets grew and register files became cheap and abundant, instruction formats evolved to exploit that abundance for maximum performance, a trend that instruction set architecture designers continue to navigate today when balancing code density, decode complexity, and execution throughput for new processor generations.