Introduction

An addressing mode is the rule that turns the operand field of an instruction into the operand itself. Most modes first compute an effective address (EA), the memory address where the operand lives, and then read or write that location. Modes let one short field reach a constant, a register, a fixed variable, a pointer target, an array element or a nearby instruction.

GATE asks you to compute the EA or the operand value under each mode from given register and memory contents, to count the memory references a mode costs, to work out PC-relative offsets (where the trap is the value of the PC at execution time), to trace autoincrement and autodecrement, and to match modes with the program constructs they serve. Instruction formats themselves are covered in Machine Instructions and Instruction Formats.

Prerequisites

Core concepts

Notation: AA is the address or constant field of the instruction, RR a register named in it, (x)(x) the contents of register or memory location xx, and PC the program counter.

ModeAssembly form (example)Effective addressOperandMemory references to read the operand value
Immediate#AnoneAA itself0
RegisterRnone (operand is in RR)(R)(R)0
Direct (absolute)AAA(A)(A)1
Indirect (memory indirect)@A or (A)(A)(A)((A))((A))2
Register indirect(R)(R)(R)((R))((R))1
Indexed or displacementA(R)A+(R)A + (R)(A+(R))(A + (R))1
Base registerA(B) with base register BB(B)+A(B) + A((B)+A)((B) + A)1
PC-relativeA(PC)(PC)+A(PC) + A((PC)+A)((PC) + A)1
Autoincrement(R)+(R)(R), then R←(R)+sR \leftarrow (R) + s((R))((R)) before the increment1
Autodecrement-(R)R←(R)−sR \leftarrow (R) - s first, then (R)(R)((R))((R)) after the decrement1

Here ss is the size of the operand in addressable units (1 for bytes, 4 for 32-bit words in a byte-addressable memory).

Indexed and base addressing compute the same sum; the difference is intent. In indexed addressing the instruction field is the array's start and the register holds the offset; in base addressing the register holds a start (the base of a program or record) and the field is the offset. Stack (implied) addressing uses the stack pointer without naming it: PUSH is autodecrement on SP and POP is autoincrement, for a stack that grows toward lower addresses.

Which mode serves which construct

Program constructNatural mode
ConstantsImmediate
Local variables held in registersRegister
Global or static variablesDirect
Pointer dereference *pRegister indirect (memory indirect if p itself is in memory)
Array element a[i]Indexed (with scaling by the element size)
Field of a record or a local in a stack frameBase plus displacement
Relocatable or position-independent code, branchesPC-relative
Walking an array, stack push and popAutoincrement and autodecrement

How it works

The value of the PC

The processor increments the PC during the fetch, so when a PC-relative address is formed, the PC already holds the address of the next instruction. A branch at address aa of length ℓ\ell with offset dd goes to a+ℓ+da + \ell + d. (Some ISAs scale dd by the instruction size, as in the MIPS conditional branch, or define the PC differently; always use the convention the question gives.)

Effective address for each mode on one memory image
Figure 1. One instruction field (200), one register R1 holding 400, and memory cells 200, 400, 500 and 600; arrows show the effective address that each mode reaches and the operand it loads.

Algorithms and pseudocode

Text
OPERAND(mode, A, R, size)            // read-value operation, not an overwrite-only store destination
  case mode of
    IMMEDIATE:       return (A, 0)
    REGISTER:        return (reg[R], 0)
    DIRECT:          return (mem[A], 1)
    INDIRECT:        return (mem[mem[A]], 2)
    REGISTER-IND:    return (mem[reg[R]], 1)
    INDEXED:         return (mem[A + reg[R]], 1)
    PC-RELATIVE:     return (mem[PC + A], 1)      // PC = next instruction
    AUTOINC:         ea <- reg[R]; reg[R] <- reg[R] + size
                     return (mem[ea], 1)
    AUTODEC:         reg[R] <- reg[R] - size; ea <- reg[R]
                     return (mem[ea], 1)

The instruction fetch itself costs one memory reference per instruction word, on top of the counts above.

Mathematical explanation

PC-relative offset. For a branch of length ℓ\ell at address aa to target tt, the stored offset is

d=t−(a+ℓ).d = t - (a + \ell).

If the ISA stores the offset in units of instructions of size ℓ\ell, the field holds d/ℓd/\ell, and a field of kk bits in two's complement reaches targets from −2k−1ℓ-2^{k-1}\ell to (2k−1−1)ℓ(2^{k-1} - 1)\ell bytes around the next instruction.

Array element address. For an array of elements of size ss starting at bb, element a[i]a[i] (counting from 0) is at

EA=b+i s.\text{EA} = b + i\,s.

Cost of a mode. Count actual memory events: instruction-word fetches + memory reads needed to form effective addresses (such as pointer reads) + required data-value reads + destination writes. The table and OPERAND procedure count reading an operand value; do not apply that value-read step to an overwrite-only STORE destination. A one-word STORE from a register to a direct address costs 1 fetch + 1 write = 2, with no old-value read. A read-modify-write ADD does read the old destination before writing it (Example 5).

Worked examples

Example 1: one memory image, many modes (Figure 1)

The instruction LOAD R0, <operand> has address field A=200A = 200. Register R1 holds 400. Memory holds: M[200]=500M[200] = 500, M[400]=700M[400] = 700, M[500]=800M[500] = 800, M[600]=900M[600] = 900.

ModeEAValue loaded into R0
Immediate #200none200
Direct 200200500
Indirect @200M[200]=500M[200] = 500800
Register R1none400
Register indirect (R1)400700
Indexed 200(R1)200+400=600200 + 400 = 600900

Example 2: PC-relative branch

A 4-byte branch instruction sits at byte address 2000 and must reach 1980. During execution the PC holds 2004, so the offset is 1980−2004=−241980 - 2004 = -24 bytes. If the ISA counts the offset in instructions, the field holds −6-6. A common wrong answer is −20-20, which uses the branch's own address instead of the updated PC.

In a word-addressable machine, a two-word instruction at word address 300 with PC-relative offset 50 refers to 302+50=352302 + 50 = 352.

Example 3: autoincrement over an array

R1 holds 1000, the start of an array of five 4-byte integers with values 10, 20, 30, 40 and 50. The loop body ADD R0, (R1)+ runs five times with R0 starting at 0.

IterationEA usedValue addedR1 after
11000101004
21004201008
31008301012
41012401016
51016501020

R0 ends at 150 and R1 at 1020, one element past the end.

Example 4: stack with autodecrement and autoincrement

SP holds 2000 and the stack grows downward with 4-byte entries. PUSH X is MOVE -(SP), X; POP Y is MOVE Y, (SP)+. After PUSH 7, PUSH 9: SP =1992= 1992, M[1996]=7M[1996] = 7, M[1992]=9M[1992] = 9. POP gives 9 and SP =1996= 1996; a second POP gives 7 and SP =2000= 2000.

Example 5: counting memory references

A one-word instruction ADD @X, R1 adds R1 into the memory location whose address is stored at X (destination is memory indirect). References: 1 instruction fetch, 1 to read M[X]M[X] (the pointer), 1 to read the operand, 1 to write the result: 4. The same addition with the pointer in a register, ADD (R2), R1, needs 3.

Example 6: two-dimensional array

A row-major array int a[10][20] (4-byte elements) starts at 5000. Element a[3][7] is element number 3×20+7=673 \times 20 + 7 = 67, at 5000+67×4=52685000 + 67 \times 4 = 5268. With base-plus-index addressing, the base register holds 5000 and the index register holds the scaled offset 268.

Important properties and observations

  • For an operand-value read, immediate and register modes need no operand memory reference; memory-indirect needs two. An overwrite-only destination needs its EA/pointer reads and the write, not an old-value read.
  • PC-relative addresses use the updated PC, the address of the next instruction.
  • Autoincrement uses then changes the register; autodecrement changes then uses it. This pairing makes a downward-growing stack.
  • Indexed and base modes add a register and a constant; they differ only in which part is the start.
  • Indirect addressing implements pointers in memory; register indirect implements pointers in registers.
  • Position-independent code uses PC-relative addressing so it runs unchanged wherever it is loaded.
  • Common misconceptions.
    • "Immediate mode reads memory for the operand." The operand is inside the instruction, which has already been fetched.
    • "Indirect and register indirect cost the same." Memory indirect needs one more memory read.
    • "The step of autoincrement is always 1." It is the operand size in addressable units.

GATE examination perspective

  • EA TABLE. Write EA and operand for each mode separately; do not apply an extra level of indirection.
  • PC-RELATIVE. Use PC == address of the next instruction; check whether the offset is in bytes or in instructions.
  • AUTOINCREMENT TRACE. Note when the register changes relative to the access.
  • MEMORY REFERENCES. Count instruction-word fetches, pointer/EA reads, required data-value reads and destination writes. An overwrite-only STORE has no old-destination read.
  • MATCH THE USE. Arrays to indexed, pointers to register indirect, constants to immediate, relocation to base or PC-relative.
  • ARRAY ADDRESS. Row-major element number times element size plus the base.

Summary

Sources

  1. C. Hamacher, Z. Vranesic, S. Zaky, Computer Organization, 5th ed., McGraw-Hill, 2002, Chapter 2, Section 2.5 (Addressing Modes, including 2.5.1 Implementation of Variables and Constants, 2.5.2 Indirection and Pointers, 2.5.3 Indexing and Arrays, 2.5.4 Relative Addressing and 2.5.5 Additional Modes) and Section 2.8 (Stacks and Queues).
  2. D. A. Patterson, J. L. Hennessy, Computer Organization and Design: The Hardware/Software Interface, 5th ed. (MIPS edition), Morgan Kaufmann, 2013: Section 2.10 (MIPS Addressing for 32-Bit Immediates and Addresses).
  3. W. Stallings, Computer Organization and Architecture, 10th ed., Pearson: Section 13.1 (Addressing Modes).

Next steps