If youve worked with
any other assembly languages you will be familiar with the concept
of an Accumulator register.
The Accumulator, as
its name suggests, is used as a general register to accumulate the
results of a large number of instructions. It can hold an 8-bit
(1-byte) value and is the most versatile register the 8051 has due
to the shear number of instructions that make use of the
accumulator. More than half of the 8051s 255 instructions manipulate
or use the accumulator in some way.
For example, if you
want to add the number 10 and 20, the resulting 30 will be stored in
the Accumulator. Once you have a value in the Accumulator you may
continue processing the value or you may store it in another
register or in memory.
The "R" registers are
a set of eight registers that are named R0, R1, etc. up to and
including R7.
These registers are
used as auxillary registers in many operations. To continue with the
above example, perhaps you are adding 10 and 20. The original number
10 may be stored in the Accumulator whereas the value 20 may be
stored in, say, register R4. To process the addition you would
execute the command:
ADD A,R4
After executing this
instruction the Accumulator will contain the value 30.
You may think of the
"R" registers as very important auxillary, or "helper", registers.
The Accumulator alone would not be very useful if it were not for
these "R" registers.
The "R" registers are
also used to temporarily store values. For example, lets say you
want to add the values in R1 and R2 together and then subtract the
values of R3 and R4. One way to do this would be:
MOV A,R3
;Move the value of R3 into the accumulator ADD A,R4 ;Add the value of R4 MOV R5,A ;Store the resulting value temporarily in R5 MOV A,R1 ;Move the value of R1 into the accumulator ADD A,R2 ;Add the value of R2 SUBB A,R5 ;Subtract the value of R5 (which now contains R3
+ R4)
As you can see, we
used R5 to temporarily hold the sum of R3 and R4. Of course, this
isnt the most efficient way to calculate (R1+R2) - (R3 +R4) but it
does illustrate the use of the "R" registers as a way to store
values temporarily.
The "B" register is
very similar to the Accumulator in the sense that it may hold an
8-bit (1-byte) value.
The "B" register is
only used by two 8051 instructions: MUL AB and DIV AB. Thus, if you
want to quickly and easily multiply or divide A by another number,
you may store the other number in "B" and make use of these two
instructions.
Aside from the MUL
and DIV instructions, the "B" register is often used as yet another
temporary storage register much like a ninth "R" register.
The Data Pointer (DPTR)
is the 8051s only user-accessable 16-bit (2-byte) register. The
Accumulator, "R" registers, and "B" register are all 1-byte values.
DPTR, as the name
suggests, is used to point to data. It is used by a number of
commands which allow the 8051 to access external memory. When the
8051 accesses external memory it will access external memory at the
address indicated by DPTR.
While DPTR is most
often used to point to data in external memory, many programmers
often take advantge of the fact that its the only true 16-bit
register available. It is often used to store 2-byte values which
have nothing to do with memory locations.
The Program Counter
(PC) is a 2-byte address which tells the 8051 where the next
instruction to execute is found in memory. When the 8051 is
initialized PC always starts at 0000h and is incremented each time
an instruction is executed. It is important to note that PC isnt
always incremented by one. Since some instructions require 2 or 3
bytes the PC will be incremented by 2 or 3 in these cases.
The Program Counter
is special in that there is no way to directly modify its value.
That is to say, you cant do something like PC=2430h. On the other
hand, if you execute LJMP 2430h youve effectively accomplished the
same thing.
It is also
interesting to note that while you may change the value of PC (by
executing a jump instruction, etc.) there is no way to read the
value of PC. That is to say, there is no way to ask the 8051 "What
address are you about to execute?" As it turns out, this is not
completely true: There is one trick that may be used to determine
the current value of PC. This trick will be covered in a later
chapter.
The Stack Pointer,
like all registers except DPTR and PC, may hold an 8-bit (1-byte)
value. The Stack Pointer is used to indicate where the next value to
be removed from the stack should be taken from.
When you push a value
onto the stack, the 8051 first increments the value of SP and then
stores the value at the resulting memory location.
When you pop a value
off the stack, the 8051 returns the value from the memory location
indicated by SP, and then decrements the value of SP.
This order of
operation is important. When the 8051 is initialized SP will be
initialized to 07h. If you immediately push a value onto the stack,
the value will be stored in Internal RAM address 08h. This makes
sense taking into account what was mentioned two paragraphs above:
First the 8051 will increment the value of SP (from 07h to 08h) and
then will store the pushed value at that memory address (08h).
SP is modified
directly by the 8051 by six instructions: PUSH, POP, ACALL, LCALL,
RET, and RETI. It is also used intrinsically whenever an interrupt
is triggered (more on interrupts later. Dont worry about them for
now!).