When a processor executes an instruction, it must determine where the required operand is located. The operand may already be part of the instruction, stored in a CPU register, or placed somewhere in memory. The method used to locate that operand is called an addressing mode.
Addressing modes are therefore closely related to instruction execution and memory access. Instead of using one fixed method for every instruction, a processor can use different addressing techniques depending on the type of data being processed. For example, a constant value can be placed directly inside an instruction, while an array element can be located by combining a base address with an index.
The choice of addressing mode affects the instruction format, number of memory accesses, amount of storage required for the instruction, and sometimes the overall execution cost. This is why addressing modes are an important part of Computer Organization and Architecture (COA).
An addressing mode is the rule used by the CPU to determine the location of an operand specified by an instruction.
Consider a simple instruction such as:
LOAD 500
The meaning of 500 depends on the addressing mode selected by the instruction. It may represent an actual memory address, a constant value, or information that must be used to calculate another address.
The processor uses the addressing mode to determine how the operand should be interpreted before the instruction is executed.
Different programs require different ways of accessing data. A compiler may need to work with constants, variables, arrays, pointers, stack frames, and branch targets. One addressing technique cannot handle all of these situations efficiently.
For example:
Thus, addressing modes provide different ways of describing where operands are located without requiring every instruction to use the same address format.
The commonly discussed addressing modes in Computer Organization include:
Not every processor implements exactly the same set of addressing modes. The available modes depend on the processor's instruction-set architecture.
The Effective Address (EA) is the memory address obtained after applying the addressing rule specified by an instruction. When an operand is stored in memory, the CPU uses the effective address to locate that operand.
The method used to obtain EA changes from one addressing mode to another.
| Addressing Mode | Effective Address Concept |
|---|---|
| Immediate | Operand is already present in the instruction. |
| Direct | EA = Address field |
| Indirect | EA = Contents of the address field |
| Register | Operand is available in the specified register. |
| Register Indirect | EA = Contents of the specified register |
| Indexed | EA = Address field + Index register |
| Relative | EA = PC + Displacement |
| Base Register | EA = Base register + Displacement |
The term EA is particularly important in memory-based addressing modes because it represents the address that the processor ultimately uses to access the operand.
In implied addressing, the instruction does not explicitly specify the operand. The processor already knows which operand is associated with that particular instruction.
This is possible because the instruction definition itself determines the operand. A common example is an accumulator-based operation.
CMA
Here, CMA means complement accumulator in instruction sets that provide this operation. The accumulator is understood automatically; the instruction does not need to contain a separate operand address.
Stack addressing uses the processor's stack mechanism to obtain operands. A stack follows the Last In, First Out (LIFO) principle, so the most recently inserted item is normally the first one removed.
The Stack Pointer (SP) identifies the current position of the stack. Stack-based addressing is useful for expression evaluation, temporary values, procedure calls, and return information.
PUSH A POP B
The exact interpretation of these instructions depends on the processor architecture, but conceptually PUSH places data on the stack and POP removes data from it.
In immediate addressing, the actual operand value is included inside the instruction. The processor does not have to obtain that operand from a separate memory location.
MOV R1, #25
Here, 25 is the value to be placed in register R1. It is not interpreted as a memory address.
The symbol # is commonly used in assembly-language notation to indicate an immediate value, although the exact syntax varies between processor architectures.
MOV R1, #25
This means the value 25 is used directly.
MOV R1, 25
Depending on the processor's assembly syntax, the second form may represent a memory location or another addressing interpretation. Therefore, the addressing mode must be understood before interpreting an instruction.
The size of an immediate value is restricted by the instruction format. A very large constant may therefore require a different instruction sequence.
In direct addressing, the address field of the instruction directly identifies the memory location containing the operand.
EA = Address Field
LOAD 500
If the instruction uses direct addressing, the processor interprets 500 as the memory address containing the required operand.
Suppose:
Memory[500] = 75
Then the instruction retrieves the value 75 from memory location 500.
The amount of memory that can be directly addressed depends on the number of address bits available in the instruction's address field.
In indirect addressing, the address field does not directly identify the operand. Instead, it identifies a location containing the address of the operand.
EA = Memory[Address Field]
Suppose an instruction contains address 500 and the memory contains:
Memory[500] = 900 Memory[900] = 75
The processor first reads location 500 and obtains 900. It then uses 900 as the effective address and reads the operand from that location.
EA = Memory[500] EA = 900 Operand = Memory[900] Operand = 75
This additional level of addressing makes indirect addressing more flexible, particularly when the actual operand location can change during program execution.
Indirect addressing generally requires an extra memory access compared with direct addressing because the processor must first obtain the actual operand address.
In register addressing, the operand is stored in one of the processor's registers. The instruction specifies which register should be used.
ADD R1
If R1 contains 40, the processor uses that register value as the operand for the addition operation.
R1 = 40
Unlike memory-based addressing, the operand is already inside the CPU's register set.
Register indirect addressing uses a register to hold the memory address of the operand. The register therefore contains an address rather than the actual data.
EA = Contents of Register
Assume:
R1 = 800 Memory[800] = 60
If an instruction uses R1 as a register-indirect address, the processor interprets 800 as the effective address and obtains the operand from memory location 800.
EA = R1 EA = 800 Operand = Memory[800] Operand = 60
This technique is useful when the memory location of data is stored in a register, such as during pointer-based data access.
Indexed addressing calculates an operand address by combining an address field with the value contained in an index register. It is particularly useful when a program needs to access elements located at different offsets from a starting address.
EA = Address Field + Index Register
Suppose an array begins at address 1000 and the index register contains an offset of 8:
Address Field = 1000 Index Register = 8 EA = 1000 + 8 EA = 1008
The processor can therefore access the data located at address 1008.
The exact interpretation of the index value depends on the architecture and data representation. For example, some systems require the index to be scaled by the size of each array element.
Relative addressing calculates the target address using the current value of the Program Counter (PC) and a displacement supplied by the instruction.
EA = PC + Displacement
Suppose:
PC = 2000 Displacement = 120
Then:
EA = 2000 + 120 EA = 2120
The processor can use this calculated address as the target of a branch or related control-transfer instruction.
Relative addressing is useful because the target can be represented as an offset from the current instruction location rather than requiring the complete target address to be stored in every instruction.
In base register addressing, a register stores the starting address of a memory region and the instruction supplies a displacement. The processor adds the two values to obtain the effective address.
EA = Base Register + Displacement
Base Register = 4000 Displacement = 120 EA = 4000 + 120 EA = 4120
This method is useful when several related data items are located at different offsets from a common starting address.
In auto increment addressing, a register contains the address of the operand. After the operand is accessed, the register is automatically increased.
EA = R R = R + Increment
For example, assume R1 contains 1000. The processor can access the operand at address 1000 and then update R1 so that it points to the next data item.
Initial R1 = 1000 Access address = 1000 R1 = R1 + increment
The actual increment normally depends on the processor architecture and the size of the data being accessed.
Auto decrement addressing performs the reverse operation of auto increment addressing. The register is decreased before the operand is accessed.
R = R - Decrement EA = R
Suppose R1 initially contains 1000. If the processor decrements it before accessing memory, the updated value becomes the address used for the operand.
Initial R1 = 1000 R1 = R1 - decrement EA = R1
This approach is useful for operations that move through memory in a reverse direction and is also associated with stack-oriented implementations.
| Mode | Where Operand Information Comes From | EA / Main Rule | Typical Use |
|---|---|---|---|
| Implied | Defined by instruction | No explicit address | Accumulator operations |
| Immediate | Instruction itself | Operand is included directly | Constants |
| Direct | Memory | EA = Address Field | Known memory locations |
| Indirect | Memory through another address | EA = Memory[Address Field] | Pointer-like access |
| Register | CPU register | Operand is in register | Fast register operations |
| Register Indirect | Memory address in register | EA = Register contents | Pointer-based access |
| Indexed | Address + index | EA = Address + Index | Arrays and tables |
| Relative | PC + displacement | EA = PC + Displacement | Branches and jumps |
| Base Register | Base + displacement | EA = Base + Displacement | Memory blocks and relocation |
| Auto Increment | Register-based address | Access, then increment | Sequential traversal |
| Auto Decrement | Register-based address | Decrement, then access | Reverse traversal and stacks |
Direct and indirect addressing are often confused because both involve a memory address field. The important difference is what that field represents.
| Direct Addressing | Indirect Addressing |
|---|---|
| The address field identifies the operand's memory location. | The address field identifies a location containing the operand's address. |
| One level of memory addressing is required to obtain the operand. | An additional memory lookup is normally required to obtain the operand address. |
| EA = Address Field | EA = Memory[Address Field] |
| Simple to implement. | More flexible for dynamically located data. |
The word register appears in both modes, but the register contains different information.
| Register Addressing | Register Indirect Addressing |
|---|---|
| The register contains the actual operand. | The register contains the memory address of the operand. |
| No memory lookup is required to obtain the operand itself. | Memory must be accessed using the address stored in the register. |
| Example: R1 = 50 means operand is 50. | Example: R1 = 800 means operand is stored at memory location 800. |
The number and type of memory accesses can influence instruction execution. Addressing modes that keep the operand inside the instruction or a CPU register generally avoid an additional memory read for the operand.
| Mode | Separate Operand Memory Access? |
|---|---|
| Immediate | No |
| Register | No |
| Direct | Normally one memory access |
| Register Indirect | Normally one memory access |
| Indirect | Normally more than one memory access |
The exact number of memory accesses can vary with the processor architecture, caching system, instruction type, and implementation. Therefore, these values should be understood as the basic addressing model rather than universal timing rules.
Address Field = 600 EA = 600
The operand is located at memory address 600.
Address Field = 600 Memory[600] = 1500 EA = Memory[600] EA = 1500
The processor must first obtain 1500 from memory location 600. The operand is then accessed from address 1500.
Address Field = 2000 Index Register = 15 EA = 2000 + 15 EA = 2015
PC = 5000 Displacement = 80 EA = 5000 + 80 EA = 5080
Base Register = 7000 Displacement = 250 EA = 7000 + 250 EA = 7250
Addressing modes are not merely theoretical features. They support common operations performed by processors, compilers, and operating systems.
In immediate addressing, the value written in the instruction is the operand itself. In direct addressing, the value represents a memory location.
If a register contains the actual data, register addressing is being used. If the register contains a memory address and the processor follows that address to obtain the data, register indirect addressing is being used.
Direct addressing uses the address field as the final operand address. Indirect addressing treats that field as a reference to another location that supplies the final address.
Effective-address calculation is mainly discussed for memory operands. In immediate or register addressing, the operand can already be available without calculating a conventional memory address.
Providing several addressing modes allows an instruction set to represent different data-access patterns efficiently. Instead of forcing every instruction to contain a complete memory address, the processor can use registers, offsets, constants, or relative positions as appropriate.
This flexibility can reduce instruction size in some situations, simplify access to structured data, and provide useful support for arrays, pointers, branches, and stack operations.
An addressing mode defines how a processor determines the location or value of an operand used by an instruction.
Effective Address, or EA, is the address obtained after applying the addressing rule used by an instruction to locate a memory operand.
Immediate addressing mode contains the actual operand value in the instruction.
EA = Address Field
EA = Memory[Address Field]
In register addressing, the register contains the operand. In register indirect addressing, the register contains the memory address where the operand is stored.
Indexed addressing is commonly used for accessing array and table elements because an index can be combined with a starting address.
Relative addressing uses the Program Counter together with a displacement to calculate a target address.
Indirect addressing requires the processor to obtain the actual operand address from another location before accessing the operand, adding another level of address resolution.
Addressing modes describe the different ways a processor can locate or obtain operands during instruction execution. The operand may be supplied directly by the instruction, stored in a register, located at a known memory address, or reached through an address calculation.
The most important modes to understand are immediate, direct, indirect, register, register indirect, indexed, relative, and base register addressing. Each one solves a different data-access problem. Indexed addressing is particularly useful for arrays, relative addressing is important for control transfer, and register indirect addressing is useful when addresses are maintained in registers.
A good way to master addressing modes is to focus on three questions for every mode: Where is the operand information stored? How is the effective address obtained? How many levels of memory access are involved? Once these three points are clear, the differences between addressing modes become much easier to remember and apply in COA problems.