View Course Path

Addressing modes in 8051 microcontroller

Before we go dive into the topic of this post (addressing modes in 8051), I would like to talk about addresses and data. If you understand these two things correctly, understanding the addressing modes in 8051 will be easy.

An address is the location of data (or code) in the memory. Any microcontroller needs an address to access the information that is inside the memory location.

This concept of addresses can be a bit convoluted to understand for beginners, so let us use a small analogy to get the message across.

Each house in a housing society has a postal address. Now in the case of microcontrollers, the RAM space is divided into partitions just like your housing society. And each memory location, just like your house in the neighborhood, has an address. All the data (or code) stored in your embedded system’s digital memory has an address. The microcontroller uses this address to retrieve or store data.

Now let’s understand what addressing modes are.

To build upon the analogy of addresses that we saw above, you can have multiple ways to describe your address to someone. You can either tell them the exact postal address. Or you can use landmarks. In other words, you can give out the address to your home in more than one way. That’s the concept behind addressing modes as well.

The CPU can access data from different places like registers, the memory or immediate values given by the programmer. The method (or channels) used by the CPU to access data to perform an operation is known as an addressing mode.

Let us look at the various addressing modes in 8051.

Immediate addressing mode 

In case of immediate addressing, data is directly put into a register. This mode places data directly into any destination register, including the DPTR register.


MOV A, #50H
MOV DPTR, #1180H

These might be looking like gibberish to you so let me help you understand this instruction. Any instruction in the 8051 microcontroller has two parts, an opcode, and an operand. The opcode tells the microcontroller what to do, whereas the operand holds the data on which the operation is to be performed. Let’s take a look at the first instruction.

  • The MOV keyword is the opcode which tells the microcontroller to move data.
  • ‘A’ keyword tells the microcontroller to store the data in the accumulator (the destination).
  • ‘#’ directs the microcontroller to store immediate data (50H) in the accumulator (the source).

Register addressing mode

As the name suggests, in this mode, the source and destination of the instruction are both registers.



The instruction mentioned above will move the contents of the R0 register to the accumulator.

The source and the destination can be the Accumulator or a register from the 32 registers available to us (Eight registers across four register banks. See the post on General purpose registers for more information). The source and the destination cannot be just registers. One of them has to be an accumulator.

Additionally, the size of both the register between which the transfer occurs should be the same size.

MOV R0,R7 //is invalid

To perform the above operation using register addressing the accumulator has to be used as an intermediate register.

MOV DPTR, R0 //is invalid
MOV DPH, R0 //is valid
MOV DPL, R1 //is valid

Direct addressing mode

In the direct addressing mode, the source and destination can be either a register or a RAM location. But both can’t be the same. If one’s a register, the other will be a RAM location.


The direct addressing mode is often used to access the regions spanning the general-purpose RAM (00H to 7FH) and the Special Function Registers (80H to FFH).

MOV R0, #55H ;indirect addressing places value 55h in r0
MOV A, R0 ;direct addressing places the value 55h in accumulator

Note: MOV A, 0 can also be used instead of the above-mentioned command

MOV R0, 55H ;places the value at memory location 55H into ro

Using direct addressing to configure SFR registers

MOV A, #55H
MOV P1, A  ;configures alternate ports of 8051 as input ports

Indirect Addressing 

Indirect addressing accesses the data at the address placed inside a register. We use the @ symbol for this purpose. This can get a little confusing so let us look an example.


MOV R0, #55H //Places value 55H in R0(Indirect addressing)
MOV R1, #56H
MOV A,@R0 //Places the data stored in memory location 55H to accumulator
MOV @R1, A //Places content of accumulator in memory location 56H
When the @ symbol is used before any register it signifies that the register is being used as a pointer to a location and the data inside that register will be used as an address. In other words, @ is used to indicate “data is at the location.”

Advantage of Indirect addressing

Indirect addressing makes the processes of accessing data dynamic when compared to direct addressing methods. In case of direct addressing if a value has to be kept at multiple memory locations values have to be inserted repeatedly. Whereas if Indirect addressing is used, a loop can be used, making the process more efficient.

Let us try to place the value 55H  into RAM locations 40H  and 45H using both direct and indirect addressing to make you familiar with the process.

  • Direct Addressing
MOV A, #55H //load A with value 55H
MOV 40H, A //copy A to RAM location 40H
MOV 41H, A //copy A to RAM location 41H
MOV42H, A //copy A to RAM location 42H
MOV 43H, A //copy A to RAM location 43H
MOV  44H, A //copy A to RAM location 44H
  • Indirect addressing
MOV A, #55H //Places 55H into accumulator
MOV R0,#40H //Initial memory location
MOV R2, #05H //counter to reach last memory location
AGAIN : MOV @R0, A //Loop statement to place values at memory locations 40H-45H
INC R0 //Increases the value of R0
DJNZ R2, AGAIN //loop until R2 is zero

Limitations of Indirect addressing

Only the registers in the register banks can be used to hold memory addressed. As these registers are 8 bit, they can only address the memory locations in the RAM space. To access the 4K ROM on the 8051 microcontroller, the DPTR register is required.

Indexed Addressing mode 

In this mode, we add the content of the accumulator with the contents of a 16-bit register to get the address at which our source data is located.

The 16-bit register, either the program counter (PC) or the data pointer (DPTR), is used to hold the base address. And the accumulator keeps the offset address. The offset gets added to the base, and the address from that particular memory location is extracted, and the operation is performed on it. This method is widely used to access data in ROM space.


MOV A, #10H //moves the value 10H in the accumulator

MOV DPTR, #0180H //moves the value 0180H in DPTR

MOVC A, @A+DPTR  //It adds the offset(10H) value in accumulator to the base (0180H) value in 
                 DPTR and then places the values located at address 0190H (0180H+10H) into the accumulator.
Note: The MOVC instruction is used instead of the MOV instruction to access data in the code space/program memory. The MOVX command gets data from an externally connected ROM which might be used to increase the program memory. MOVC can only retrieve data from the program memory. MOVX can retrieve as well as store data from/into the external ROM. To get a better understanding, let’s look at a few examples. We’ll take a look at the difference between MOVX, MOVC, and MOV in detail in our post on the 8051’s instruction set.

Implied addressing mode 

In the implied or implicit addressing mode, the instructions perform operations on registers. These instructions don’t have any source or destination operands.


RLA //This instruction shifts the data in the register to the lest and appends 0 to the right
SWAPA //This instruction swaps the upper 4 bits with the lower 4 bits.

We hope reading this article helped you understand the addressing modes in 8051 in a better way. If you have any issues in the topic feel free to ask your doubts in the comments section below

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.