Addressing Mode refers to the way the actual location of an instruction’s operand is specified. It is used in the decode phase of the instruction cycle to extract the operand of the instruction so the proceeding execute phase can start. The main purpose of having different addressing modes is to provide flexibility when referencing the memory location of the operand. The operand may be located in a memory address, a processor register or its value may be directly encoded into the instruction without the need to reference a memory location.
The most common ways of specifying which addressing mode is going to be used are:
- having different opcodes for the various addressing modes
- selected by a dedicated bits part of the instruction format

Fig.1 An example instruction format
The effective address is the actual location (in main memory or CPU register) of the operand. It may be directly specified in the instruction or it can be derived based on some additional rules specific to the addressing mode used by the instruction.
The addressing modes are hidden when using a high level language like C, but are easily distinguished when assembly language is used.
In this article we will cover the most common addressing modes. Keep in mind that there are no strict naming rules for the addressing modes, so depending on the author and CPU manufacturer the same addressing mode can have different name.
We use ARM instruction set for the examples below. Comments in the code are denoted using “;”.
Immediate Addressing
In this addressing mode the operand value is directly specified in the instruction. It can be used to define constants and set initial values of variables.
Specifics:
- Fast
- Range of the operand is limited by the number of bits in the operand field
Example:
ADD r4, r4, #5 ; Add the contents of register r4 with the contstant value 5 ;and store the result in register r4
The above instruction can be written using the shorter so called “two-operand format” :
ADD r4, #5 ;
Direct (Absolute) Addressing
In addressing mode the effective address of the operand is directly specified in the instruction. The addressable space is limited by the size of the field (address field) in the instruction.
Example:
ADD r1, (901) ;Add the value stored in r1 register with the value stored in memory address 901 and store the result in register r1
This mode is not supported by the ARM instruction set, due to its load and store architecture it does not perform operations with operands directly from the memory.
Register Addressing
In this addressing mode the operand is located in one of the CPU’s general purpose registers. Which register contains the operand is specified by the instruction.
Example:
ADD r2, r3 – adds the contents of r2 to the contents of r3 (r2= r3 + r2)
Advantages:
- Only few bits in the instruction are required to specify the register containing the operand
- No time-consuming memory references are required
- Fast access to the operand – the access to the CPU internal register is quicker than the access a main memory address
Disadvantages:
- The address space is small as it is limited by the available CPU general purpose registers.
Register Indirect Addressing
In this addressing mode the address of the operand is held in a CPU register. It is also known as indexed addressing or base addressing. It is used to provide an efficient way of performing iterative operations and array addressing.
Example:
ADD r3, [r2]
LDR r4, [r5] ; Load R4 with the data pointed by R5
Register Indirect Addressing with an Offset
In this addressing mode the effective address of the operand is calculated by adding the content of a register and an offset coded into load/store instruction.
Example:
LDR r3, [r2, #20] ; loads r3 with the word pointed by r2+20
Autoindexing Pre-indexed Addressing Mode
In this addressing mode the effective address of the operand is specified as the sum of the contents of a general purpose register r[n] (called pointer register in this case) and an offset value (literal).
This addressing mode is useful when accessing sequential data in arrays.
Example:
LDR r0, [r1, #4]! ; loads r0 with the data pointed by r1+4 ; then update the pointer (r1) by adding 4 to it
Autoindexing Post-indexing Addressing Mode
In this addressing mode the effective address of the operand is the contents of a general purpose register r[n]. An offset is added to this address and the result is written back into the register r[n].
It is similar to the Autoindexing Pre-indexed Addressing Mode, but here the operand pointed by the register is accessed, and then the register value (pointer) is incremented by the specified offset.
Example:
LDR r0, [r1], #4 ; loads r0 with the data pointed by r1 ; then update the pointer (r1) by adding 4 to it
Program Counter Relative Addressing Mode
In ARM ISA register r15 is used as the program counter The operand in this addressing mode is specified with respect to the current program counter value.
Example:
LDR r0, [r15, #24] ; loads r0 with the data pointed by r15+24
Leave A Comment