optional · CSS study notes
Machine Instructions
CSS Optional — Paper-II, Section-A · Chapter 7 · 🔥 Frequently repeated topic
An instruction is the fundamental unit of work a CPU understands. This topic covers how instructions are encoded (instruction format), what kinds exist (instruction types), and how they locate their operands (addressing modes — the highest-yield part).
🗺️ Architecture Diagram — Instruction Format and Addressing Modes
graph TD
INSTR["Instruction"] --> OP["Opcode Field
what to do"]
INSTR --> ADDR["Operand / Address Field
where the data is"]
ADDR --> IMM["Immediate: value in instruction"]
ADDR --> DIR["Direct: EA = address field"]
ADDR --> IND["Indirect: EA = Mem of address field"]
ADDR --> REGM["Register: operand in Rn"]
ADDR --> REGI["Register Indirect: EA = Rn"]
ADDR --> IDX["Indexed: EA = Base + Index"]
ADDR --> REL["Relative: EA = PC + Offset"]
1. Instruction Format
Every machine instruction has two parts:
┌──────────┬─────────────────────────────┐
│ OPCODE │ OPERAND / ADDRESS FIELD │
└──────────┴─────────────────────────────┘
- Opcode — specifies what operation to perform. If a machine supports 2ᵏ operations, the opcode needs k bits.
- Operand field(s) — specify where the data is. May contain a register number, a memory address, or an immediate value.
Format length trade-off: fixed-length instructions (RISC) simplify decoding and enable pipelining; variable-length instructions (CISC) save memory but complicate decoding. See CISC vs RISC.
2. Instruction Types
| Category | Purpose | Examples |
|---|---|---|
| Data transfer | Move data between registers, memory, and I/O | MOV, LOAD, STORE, PUSH, POP |
| Arithmetic | Numeric computation | ADD, SUB, MUL, DIV, INC, DEC |
| Logical | Bitwise operations and shifts | AND, OR, NOT, XOR, SHL, SHR |
| Control transfer | Alter the sequence of execution | JMP, CALL, RET, conditional branches (JZ, JNZ) |
| I/O | Communicate with peripherals | IN, OUT |
| System control | Privileged operations | HALT, interrupt instructions |
Note: data transfer instructions never change the data; they only relocate it. Control transfer instructions work by overwriting the PC.
3. Addressing Modes ⭐ (highest-yield section)
An addressing mode is the rule by which the CPU computes the effective address (EA) — the actual location of the operand.
Why so many modes? The address field of an instruction is small, but programs need constants, variables, pointers, arrays, records and branches. Each mode is a different rule for turning the few bits in the instruction into the real location of the data, so a short instruction can still reach any data in memory.
Notation used below:
- — the address (or value) field of the instruction
- and — a register, and the contents of that register
- — the contents of memory location
- — the effective address, the final address of the operand
- — program counter, — index register, — base register
- Mode field: a few bits of the instruction (the mode bits) tell the CPU which rule to apply.
How to Read the Assembly Examples
The examples below use a simple textbook accumulator machine, so that one line of assembly shows one idea. It is not a real assembler, but real ones (MIPS, x86) follow the same pattern, and they are explained at the end of this subsection.
- Instruction form:
OPCODE operand ; comment. The text after;is only a comment for the reader. - The accumulator ACC is implied. In
ADD 500the first operand and the destination is always ACC, so it means . - The way the operand is written decides the mode:
| How it is written | How to read it | Mode |
|---|---|---|
ADD #5 | # means the number itself, not an address | Immediate |
ADD 500 | A bare number is a memory address | Direct |
ADD (500) | Brackets mean "the contents of", so location 500 holds another address | Indirect |
ADD R1 | A register name means the value in that register | Register |
ADD (R1) | The register holds the address of the operand | Register indirect |
ADD 3000(XR) | A number with a register in brackets means number + register | Indexed |
ADD 24(BR) | The same pattern, but the register is a base register and the number is a fixed offset | Base + displacement |
JMP +40 | An offset from the current PC | Relative |
ADD (R1)+ and ADD -(R1) | The register is raised after the access, or lowered before it | Auto-increment and auto-decrement |
- The arrow means "is replaced by" (a register transfer): copies the contents of location 500 into ACC.
What the CPU does for one instruction (taking ADD 500 as the example). Every instruction goes through the instruction cycle:
Only the operand-fetch step changes from one mode to the next. This is what each assembly form makes the hardware do:
| Mode | Assembly | Operand-fetch steps | Memory reads |
|---|---|---|---|
| Immediate | ADD #5 | MBR ← A (the value is already in the instruction register) | 0 |
| Register | ADD R1 | MBR ← (R1) | 0 |
| Direct | ADD 500 | MAR ← A; MBR ← M[MAR] | 1 |
| Register indirect | ADD (R1) | MAR ← (R1); MBR ← M[MAR] | 1 |
| Indirect | ADD (500) | MAR ← A; MBR ← M[MAR] (this is the address); MAR ← MBR; MBR ← M[MAR] (this is the operand) | 2 |
| Indexed | ADD 3000(XR) | MAR ← A + (XR); MBR ← M[MAR] | 1 |
| Base + displacement | ADD 24(BR) | MAR ← (BR) + 24; MBR ← M[MAR] | 1 |
| Relative (branch) | JMP +40 | EA ← PC + 40; PC ← EA (the "operand" is the target address, so no data is read; a PC-relative data access adds MBR ← M[EA]) | 0 for a branch, 1 for data |
A small program, line by line (direct and immediate modes together). The task is to add 5 to the number stored at location 500 and keep the result at location 504:
LOAD 500 ; ACC <- M[500] (direct)
ADD #5 ; ACC <- ACC + 5 (immediate)
STORE 504 ; M[504] <- ACC (direct)
Trace when :
Why indexed addressing suits arrays: the instruction ADD 3000(XR) is written once, and only the register changes in each loop pass. With the array at 3000 and 4-byte elements:
Real assembly languages use the same ideas with a different syntax:
- MIPS
lw $t0, 8($s1):lwis load word,$t0is the destination register, and8($s1)is the displacement 8 plus the base register$s1. As a transfer: . - x86
MOV EAX, [EBX + ESI*4 + 8]:MOVcopies into the first operand (the destination comes first),EAXis the destination, and the square brackets mean "the memory at the address inside". The address is baseEBX+ indexESI× scale 4 + displacement 8. As a transfer: . - Implied mode:
CLC(clear carry flag) andINChave no operand field, because the opcode already says what to act on.
(a) Immediate Addressing
The operand is the value, stored inside the instruction itself.
Assembly: ADD #5 (add the literal value 5)
Example: with :
- ✅ Fastest — zero memory references beyond the instruction fetch.
- ❌ Operand size limited by the field width; the value is fixed at compile time.
- Use: initialising constants, loop counters.
(b) Direct (Absolute) Addressing
The instruction contains the address of the operand.
Assembly: ADD 500 (add the contents of memory location 500)
Example: with and :
- ✅ Simple; one memory access for the operand.
- ❌ Address space limited by field width; address fixed at compile time.
(c) Indirect Addressing
The instruction contains the address of a location that itself contains the operand's address — a double dereference.
Assembly: ADD (500) (location 500 holds the real address)
Example: with , and :
- ✅ Large address space reachable from a small field; supports pointers.
- ❌ Two memory accesses to fetch one operand — slow.
(d) Register Addressing
The operand is in a CPU register.
Assembly: ADD R1 (the operand is the contents of R1)
Example: with and :
- ✅ Fastest operand access after immediate — no memory reference at all; short instruction encoding.
- ❌ Limited by the number of registers available.
(e) Register Indirect Addressing
The register holds the address of the operand.
Assembly: ADD (R1)
Example: with , and :
- ✅ One memory access; the address can be computed at runtime — the basis of pointer arithmetic in C.
(f) Indexed Addressing
Here is the start of the array (in the instruction) and is the contents of the index register (element number × element size).
Example: the array starts at 3000 and (element 3 × 4 bytes):
- The workhorse of array access. The base is the array's start; the index register holds the element number (scaled by element size).
- ✅ Enables loops over arrays with a single instruction per iteration.
(g) Base-Register (Displacement) Addressing
Here is the contents of the base register and is the displacement (offset) in the instruction.
Example: a record is loaded at 6000 () and the field is at offset 24:
If the operating system moves the record, only changes, and the instruction stays the same. That is why this mode helps relocation.
- Similar arithmetic to indexed, but the base is in a register and the offset is constant, whereas indexed has a constant base and a varying register index. Used for accessing fields within a structure and for relocatable code.
(h) Relative (PC-Relative) Addressing
Example: (already pointing to the next instruction) and the offset is :
- Used for branches. Because the target is expressed as a distance rather than an absolute address, the code can be loaded anywhere in memory without modification — this is what makes position-independent code possible.
(i) Implied / Implicit Addressing
The operand is implicit in the opcode itself.
CLC ; clear carry flag — no operand field at all
INC ; increment the accumulator
(j) Auto-increment and Auto-decrement
Register indirect addressing in which the register is updated automatically by the size of the operand (1, 2 or 4 bytes).
Example: and :
- ✅ Steps through an array or string with no separate increment instruction. Together they also give the stack operations PUSH (decrement, then store) and POP (load, then increment).
- ❌ The register changes as a side effect, which complicates pipelining and exception handling.
(k) Scaled Index Addressing (x86)
The element number is multiplied by the element size inside the address calculation.
Example: MOV EAX, [EBX + ESI*4 + 8] with , :
- ✅ One instruction reaches element of an array of 4-byte items, so the programmer does not scale the index by hand.
- ❌ Complex address hardware, so it is found in CISC but not in RISC.
(l) Stack Addressing
The operand is at the top of the stack, and the stack pointer (SP) gives its address, so the instruction needs no address field (zero-address instructions such as ADD, PUSH, POP).
Example: , (the stack grows downward):
- Use: evaluating expressions and handling procedure calls (return address, parameters, local variables).
Which Mode for Which Job
| Programming need | Best mode | Why |
|---|---|---|
| A constant (x = 5) | Immediate | The value is inside the instruction |
| A simple variable | Direct or register | The address is known at compile time |
| A pointer (*p) | Indirect or register indirect | The address is itself stored in a variable |
| An array element A[i] | Indexed or scaled index | The base stays fixed and the index changes |
| Walking through an array or string | Auto-increment | The pointer moves on by itself |
| A field of a record or a local variable | Base + displacement | The base is the start of the record or stack frame, and the field offset is fixed |
| A branch, loop or if-statement | Relative | The target is a short distance away and the code can be moved anywhere |
| Expression evaluation, procedure calls | Stack | Last in, first out |
Summary Table
| Mode | Effective address | Memory accesses for operand | Speed |
|---|---|---|---|
| Immediate | — (operand in instruction) | 0 | Fastest |
| Implied | — (operand implicit) | 0 | Fastest |
| Register | — (operand in register) | 0 | Very fast |
| Register indirect | EA = R | 1 | Fast |
| Direct | EA = address field | 1 | Moderate |
| Indexed | EA = Base + Index | 1 | Moderate |
| Base + displacement | EA = Base reg + Offset | 1 | Moderate |
| Relative | EA = PC + Offset | 1 | Moderate |
| Indirect | EA = Memory[address field] | 2 | Slowest |
🧮 Solved Numerical 1 — Effective Address Across Modes
Q: Given: instruction address field = 400, Memory[400] = 700, Memory[700] = 900, R1 = 200, Memory[200] = 350, PC = 1000, Index register = 50, Memory[450] = 520, Memory[1400] = 640. Find the operand under each addressing mode.
Given: , , , , , , , , .
Step-by-step working:
Result table:
| Mode | Effective address | Operand |
|---|---|---|
| Immediate | None | 400 |
| Direct | 400 | 700 |
| Indirect | 700 | 900 |
| Register | None | 200 |
| Register indirect | 200 | 350 |
| Indexed | 450 | 520 |
| Relative | 1400 | 640 |
Answer as above. This single-table format — one set of given values, every mode applied — is precisely how this question is usually set, so practise it in exactly this layout.
🧮 Solved Numerical 2 — Array Access via Indexed Addressing
Q: An integer array starts at address 3000. Each element is 4 bytes. Using indexed addressing, find the effective address of element A[7].
Given: base address , element size bytes, index (indexing starts at 0).
Formula:
Working:
If the array is numbered from 1 (Pascal, FORTRAN), the formula becomes:
Answer: 3028.
Note the scaling by element size — omitting it is a common error. Element A[0] is at 3000, A[1] at 3004, and so on.
🧮 Solved Numerical 3 — Instruction Format Design
Q: A machine has a 16-bit instruction, must support 32 distinct operations, and uses direct addressing. How many memory locations can it address?
Given: instruction length = 16 bits, number of operations = 32, direct addressing.
Step 1 — Opcode bits:
Step 2 — Address bits:
Step 3 — Addressable locations:
Answer: 2,048 locations.
Follow-up worth adding in the exam: this illustrates the fundamental tension in instruction format design — every bit given to the opcode is a bit taken from the address field. Supporting more operations means addressing less memory. Indirect addressing exists precisely to escape this limit.
🧮 Solved Numerical 4 — Memory Accesses and Timing
Q: Each memory access takes 20 ns. Compare the total operand-fetch time for direct versus indirect addressing.
Given: memory access time .
Formula:
Working:
Answer: Direct 20 ns, Indirect 40 ns — indirect is 2× slower. This is the concrete cost of the flexibility indirect addressing provides.
🧮 Solved Numerical 5 — Relative Branch Range
Q: A branch instruction uses PC-relative addressing with a signed 8-bit offset. If PC = 5000, what is the range of addresses the branch can reach?
Given: , offset is a signed 8-bit number.
Step 1 — Offset range:
Step 2 — Target range:
Step 3 — Number of reachable addresses:
Answer: 4872 to 5127. This limited range is why compilers occasionally generate a "branch to a jump" — the intended target lies outside the reachable window.
🧮 Solved Numerical 6 — Instruction Format with a Mode Field
Q: A 16-bit instruction has a 4-bit opcode and a 3-bit addressing-mode field. The remaining bits form the address field. How many operations and modes can it support, and how much memory can the address field reach directly?
Step-by-step working:
Answer: 16 operations, 8 modes, 512 locations. Every extra field takes bits from the address field. Without the mode field the same instruction could address locations, and the modes are what let it reach the rest of memory indirectly.
🧮 Solved Numerical 7 — Average Memory Accesses per Instruction
Q: Each instruction has one instruction fetch and one operand. The operand modes are immediate 10%, register 40%, direct 20%, indirect 10% and indexed 20%. A memory access takes 20 ns. Find the average memory accesses per instruction and the average memory time.
Step 1 — Check the fractions:
Step 2 — Operand accesses for each mode: immediate 0, register 0, direct 1, indirect 2, indexed 1.
Step 3 — Average operand accesses:
Step 4 — Add the instruction fetch and find the time:
Answer: 1.60 accesses and 32 ns per instruction. Indirect addressing is only 10% of the operands but causes of the operand accesses, which is the cost of its flexibility. The instruction fetch is counted in the total, as in the effective-CPI problems on the Performance Metrics page.
🎯 CSS Exam Angle
Addressing modes are among the most repeated short questions in this chapter. Examiners almost always want:
- The mode named, defined, and given an example — not just listed.
- The effective address formula written explicitly for each.
- A worked example showing the operand actually retrieved (Numerical 1's layout).
- A closing line on the trade-off: speed decreases as flexibility increases, from immediate (0 memory accesses) through to indirect (2).
Mentioning why each mode exists — indexed for arrays, relative for relocatable code, register indirect for pointers — is what lifts an answer above a memorised list.
🔁 Repeated CSS Questions
- Explain the different addressing modes with examples. (Very frequently repeated — treat as near-certain)
- Differentiate between direct and indirect addressing modes. (MCQ favourite)
- What is an instruction format? Explain the roles of the opcode and operand fields.
- Calculate the effective address for a given addressing mode and set of values. (Numerical)
- Which addressing mode is most suitable for accessing array elements, and why?
- Given an instruction length and number of operations, determine the addressable memory. (Numerical)
- Classify machine instructions by type with examples.
⚠️ MCQ Traps
- Indirect addressing requires TWO memory accesses, direct requires one, and immediate/register require zero. Access count is the most common MCQ discriminator here.
- In indirect addressing the field holds the address OF an address, not the data. Candidates routinely describe direct addressing when asked about indirect.
- Immediate addressing is the fastest, but the operand is fixed at compile time and cannot be a variable.
- Indexed vs base-register addressing: in indexed mode the base is constant and the index register varies; in base-displacement mode the base register varies and the offset is constant. The arithmetic is identical; the roles are reversed.
- Relative addressing is used for branches, not for data access, and it is what makes position-independent code possible.
- A larger opcode field means a smaller address field in a fixed-length instruction — they compete for the same bits.
📜 Past-Paper Questions & MCQs (CSS 2016–2026)
2021 · Paper-II · Q2(a) · 10 marks
Q. Examine any five addressing modes with an example based on the contents of the address field, the actual (effective) address and the contents of the memory location.
Ans. Assume the address field A = 500, register R1 = 400, and memory: M[500] = 800, M[800] = 300, M[400] = 250, M[900] = 700.
| Mode | Effective address | Operand obtained | Note |
|---|---|---|---|
| Immediate | None | 500 (the field itself) | No memory access, fastest |
| Direct (absolute) | EA = A = 500 | M[500] = 800 | One memory access |
| Indirect | EA = M[500] = 800 | M[800] = 300 | Two memory accesses, flexible |
| Register direct | None (the field names a register) | R1 = 400 | No memory access |
| Register indirect | EA = R1 = 400 | M[400] = 250 | Register holds the address |
| Displacement (indexed or base + offset) | EA = A + R1 = 900 | M[900] = 700 | Used for arrays and records |
Working in equation form (with the assumed values A = 500, R1 = 400, M[500] = 800, M[800] = 300, M[400] = 250, M[900] = 700):
- Memory accesses for the operand: immediate 0, register direct 0, direct 1, register indirect 1, displacement 1, indirect 2.
- Trade-off to close the answer: speed falls and flexibility rises as we move from immediate (fastest) to indirect (slowest, but it can reach any address through a pointer).
2021 · Paper-II · Q2(b) · 5 marks
Q. The address field of an instruction has the decimal value 120. The machine uses register direct and register indirect addressing. Calculate the address of the corresponding operand.
Ans.
- Register direct: the field 120 names register R120. The operand is the content of R120 itself, so there is no memory address.
- Register indirect: the field 120 names register R120, whose content is the effective address. EA = (R120), and the operand is M[(R120)]. For example, if R120 held 2000, the operand would be at memory address 2000.
Equation form (taking and as an illustration):
2021 · Paper-II · Q2(c) · 5 marks
Q. Compare the addressing modes of RISC and CISC machines. Give one example of addressing modes used in RISC and CISC respectively.
Ans.
- RISC: only a few simple modes: register, immediate and base + displacement (load/store only). Example: MIPS
lw $t0, 8($s1). - CISC: many complex modes: direct, indirect, indexed, auto-increment and decrement, scaled index. Example: x86
MOV EAX, [EBX + ESI*4 + 8]. - Effect: simple modes keep RISC decoding and pipelining easy, and complex modes make CISC programs shorter but slower to decode.
Effective-address examples in equation form:
- RISC (MIPS)
lw $t0, 8($s1)(load word into register t0 from the address base register s1 + 8), with :
- CISC (x86)
MOV EAX, [EBX + ESI*4 + 8](copy into EAX the memory at base EBX + index ESI × 4 + displacement 8), with and :
2025 · Paper-II · Q2(c)(i) · 5 marks
See the RISC versus CISC addressing-mode answer above (the same question as 2021 Q2(c)).