An "addressing mode" refers to
how you are addressing a given memory location. In summary, the
addressing modes are as follows, with an example of each:
Immediate Addressing
MOV A,#20h
Direct Addressing
MOV A,30h
Indirect Addressing
MOV A,@R0
External Direct
MOVX A,@DPTR
Code Indirect
MOVC A,@A+DPTR
Each of these addressing modes provides
important flexibility.
Immediate Addressing
Immediate addressing is so-named because the
value to be stored in memory immediately follows the operation
code in memory. That is to say, the instruction itself dictates
what value will be stored in memory.
For example, the instruction:
MOV A,#20h
This instruction uses Immediate Addressing
because the Accumulator will be loaded with the value that
immediately follows; in this case 20 (hexidecimal).
Immediate addressing is very fast since the
value to be loaded is included in the instruction. However,
since the value to be loaded is fixed at compile-time it is not
very flexible.
Direct addressing is so-named because the value
to be stored in memory is obtained by directly retrieving it
from another memory location. For example:
MOV A,30h
This instruction will read the data out of
Internal RAM address 30 (hexidecimal) and store it in the
Accumulator.
Direct addressing is generally fast since,
although the value to be loaded isnt included in the
instruction, it is quickly accessable since it is stored in the
8051s Internal RAM. It is also much more flexible than Immediate
Addressing since the value to be loaded is whatever is found at
the given address--which may be variable.
Also, it is important to note that when using
direct addressing any instruction which refers to an address
between 00h and 7Fh is referring to Internal Memory. Any
instruction which refers to an address between 80h and FFh is
referring to the SFR control registers that control the 8051
microcontroller itself.
The obvious question that may arise is, "If
direct addressing an address from 80h through FFh refers to SFRs,
how can I access the upper 128 bytes of Internal RAM that are
available on the 8052?" The answer is: You cant access them
using direct addressing. As stated, if you directly refer to an
address of 80h through FFh you will be referring to an SFR.
However, you may access the 8052s upper 128 bytes of RAM by
using the next addressing mode, "indirect addressing."
Indirect addressing is a very powerful
addressing mode which in many cases provides an exceptional
level of flexibility. Indirect addressing is also the only way
to access the extra 128 bytes of Internal RAM found on an 8052.
Indirect addressing appears as follows:
MOV A,@R0
This instruction causes the 8051 to analyze the
value of the R0 register. The 8051 will then load the
accumulator with the value from Internal RAM which is found at
the address indicated by R0.
For example, lets say R0 holds the value 40h and
Internal RAM address 40h holds the value 67h. When the above
instruction is executed the 8051 will check the value of R0.
Since R0 holds 40h the 8051 will get the value out of Internal
RAM address 40h (which holds 67h) and store it in the
Accumulator. Thus, the Accumulator ends up holding 67h.
Indirect addressing always refers to Internal
RAM; it never refers to an SFR. Thus, in a prior example we
mentioned that SFR 99h can be used to write a value to the
serial port. Thus one may think that the following would be a
valid solution to write the value 1 to the serial port:
MOV R0,#99h ;Load the address of the
serial port MOV @R0,#01h ;Send 01 to the serial port -- WRONG!!
This is not valid. Since indirect addressing
always refers to Internal RAM these two instructions would write
the value 01h to Internal RAM address 99h on an 8052. On an 8051
these two instructions would produce an undefined result since
the 8051 only has 128 bytes of Internal RAM.
External Memory is accessed using a suite of
instructions which use what I call "External Direct" addressing.
I call it this because it appears to be direct addressing, but
it is used to access external memory rather than internal
memory.
There are only two commands that use External
Direct addressing mode:
MOVX A,@DPTR
MOVX @DPTR,A
As you can see, both commands utilize DPTR. In
these instructions, DPTR must first be loaded with the address
of external memory that you wish to read or write. Once DPTR
holds the correct external memory address, the first command
will move the contents of that external memory address into the
Accumulator. The second command will do the opposite: it will
allow you to write the value of the Accumulator to the external
memory address pointed to by DPTR.
External memory can also be accessed using a
form of indirect addressing which I call External Indirect
addressing. This form of addressing is usually only used in
relatively small projects that have a very small amount of
external RAM. An example of this addressing mode is:
MOVX @R0,A
Once again, the value of R0 is first read and
the value of the Accumulator is written to that address in
External RAM. Since the value of @R0 can only be 00h through FFh
the project would effectively be limited to 256 bytes of
External RAM. There are relatively simple hardware/software
tricks that can be implemented to access more than 256 bytes of
memory using External Indirect addressing; however, it is
usually easier to use External Direct addressing if your project
has more than 256 bytes of External RAM.