| |
 |
The 8051
|
|
|
|
| |
|
| |
|
| |
Instruction Set Summary |
| |
|
| |
Instructions tell the processor which
operation to carry out. For example, MOV A, #5EH tells the processor to
move the data 5EH to the accumulator. |
| |
Instructions result in the processor
performing some operation on some data (the data being #5EH in the
example above). The instruction above is an example of what's known as immediate
addressing. The reason for this is because the data immediately
follows the instruction in code memory. |
| |
However, it is not always adequate to
store the data in code memory itself. If we needed to read the
information from a keyboard, for example, we would need to use
something other than immediate addressing. |
| |
There are eight different addressing
modes in the 8051. |
| |
|
| |
Opcode and Operand |
| |
The first byte of an instruction is
known as the opcode (operation code) because this is the byte that is
decoded by the processor - from this code the processor can work out
what operation it must perform. |
| |
For a one-byte instruction there is
only the opcode. |
| |
For a two-byte instruction the second
byte is the operand. The operand can be data or an 8-bit address. |
| |
For a three-byte instruction the
second and third bytes make up the operand. A two-byte operand is
usually a 16-bit address, as we shall see when we look at long
addressing. |
| |
|
| |
Addressing Modes |
| |
The eight addressing modes are: |
| |
- Immediate
- Register
- Direct
- Indirect
- Relative
- Absolute
- Long
- Indexed
|
| |
|
| |
Immediate Addressing |
| |
If the operand is a constant then it
can be stored in memory immediately after the opcode. Remember, values
in code memory (ROM) do not change once the system has been programmed
and is in use in the everyday world. Therefore, immediate addressing is
only of use when the data to be read is a constant. For example, if
your program needed to perform some calculations based on the number of
weeks in the year, you could use immediate addressing to load the
number 52 (34H) into a register and then perform arithmetic operations
upon this data. |
| |
MOV R0, #34
|
| |
The above instruction is an example
of immediate addressing. It moves the data 34H into R0. The assembler
must be able to tell the difference between an address and a piece of
data. The has symbol (#) is used for this purpose (whenever the
assembler sees # before a number it knows this is immediate addressing). |
| |
This is a two-byte instruction. |
| |
|
| |
|
| |
Register Addressing |
| |
Often we need to move data from a
register into the accumulator so that we can perform arithmetic
operations upon it. For example, we may wish to move the contents of R5
into the accumulator. |
| |
MOV A, R5
|
| |
This is an example of register
addressing. It moves data from R5 (in the currently selected register
bank) into the accumulator. |
| |
ADD A, R6
|
| |
The above is another example of
register addressing. It adds the contents of R6 to the accumulator,
storing the result in the accumulator. Note that in both examples the
destination comes first. This is true of all instructions. |
| |
|
| |
|
| |
Direct Addressing |
| |
Direct addressing is used for
accessing data in the on-chip RAM. Since there are 256 bytes of RAM
(128 bytes general storage for the programmer and another 128 bytes for
the SFRs). That means the addresses go from 00H to FFH, any of which
can be stored in an 8-bit location. |
| |
MOV A, 67
|
| |
The above instruction moves the data
in location 67H into the accumulator. Note the difference between this
and immediate addressing. Immediate addressing uses the data, which is
immediately after the instruction. With direct addressing, the operand
is an address. The data to be operated upon is stored in that address.
The assembler realises this is an address and not data because there is
no hash symbol before it. |
| |
ADD A, 06
|
| |
The above instruction adds the
contents of location 06H to the accumulator and stores the result in
the accumulator. If the selected register bank is bank 0 then this
instruction is the same as ADD A, R6. |
| |
|
| |
|
| |
Indirect Addressing |
| |
Register addressing and direct
addressing both restrict the programmer to manipulation of data in
fixed addresses. The address the instruction reads from (MOV A, 30H) or
writes to (MOV 30H, A) cannot be altered while the program is running. |
| |
There are times when it is necessary
to read and write to a number of contiguous memory locations. For
example, if you had an array of 8-bit numbers stored in memory,
starting at address 30H, you may wish to examine the contents of each
number in the array (perhaps to find the smallest number). To do so,
you would need to read location 30H, then 31H, then 32H and so on. |
| |
This can be achieved using indirect
addressing. R0 and R1 may be used as pointer registers. We can use
either one to store the current memory location and then use the
indirect addressing instruction shown below. |
| |
MOV A, @Ri
|
| |
where Ri is either R0 or R1. |
| |
Now, we can read the contents of
location 30H through indirect addressing: |
| |
MOV R0, #30H
MOV A, @R0
|
| |
The first instruction is an example of immediate addressing
whereby the data 30H is placed in R0. The second instruction is
indirect addressing. It moves the contents of location 30H into the
accumulator.
|
| |
If we now wish to get the data in
location 31H we use the following: |
| |
INC R0
MOV A, @R0
|
| |
Once we see how to write a loop in
assembly language, we will be able to read the entire contents of the
array. |
| |
|
| |
|
| |
Relative Addressing |
| |
Relative addressing is used only with
certain jump instructions. The system executes a jump by changing the
contents of the PC to the address of the next instruction to be
executed. For example, if we wished to jump to the instruction stored
at location 4EH in code memory, the PC would be loaded with 4EH. Then,
during the next execution cycle the contents of the PC (4EH) are placed
on the address bus and the instruction at 4EH is retrieved. |
| |
A relative address (or offset) is an
8-bit signed value, which is added to the PC to form the address of the
next instruction to be executed. |
| |
With 8-bit signed numbers, the MSB is
used to determine whether the number is positive or negative. If the
MSB is 0 then the number is positive, while if the MSB is 1 the number
is negative. |
| |
The instruction below shows how to
jump six locations ahead. |
| |
SJMP 06H
|
| |
SJUMP is an unconditional jump
and is a 2-byte instruction. The number following it is an offset
address. If this instruction were stored in code memory at locations
100H and 101H, as shown below: |
| |
100H 80H
101H 06H
|
| |
The opcode for SJMP is 80H.
The operand is the offset address. If this instruction were executed
the PC would get the value 108H. This is what happens: |
| |
- The PC contains 100H, therefore the instruction 80H is read
into the IR.
- The instruction is decoded as the 2-byte SJMP instruction.
- The PC is incremented so that the operand may be retrieved.
- The operand is read from code memory and the PC is
incremented again (because this is a 2-bye instruction).
- The operand (06H) is added to the PC (102H + 06H = 108H).
- The next instruction (at 108H) is executed.
|
| |
Once we deal with 2's compliment and
how negative numbers are dealt with in the CPU, we will look at a
backward jump. |
| |
The S in SJMP stands
for short. The range of signed 8-bit numbers is -127 to 128. (See how
signed numbers are stored in a microcontroller.) Therefore, using
SJMP allows us to jump 127 locations forward or 128 locations backward.
Hence the name short jump. |
| |
When writing assembly programs we do
not need to calculate the offset when using SJMP. Instead, we use
labels. If we wished to jump to the instruction at 108H we would simply
label the instruction with an appropriate name, for example THERE.
We would then write the assembly code SJMP THERE. The assembler
does the work of replacing the label with the correct offset. |
| |
|
| |
|
| |
Absolute Addressing |
| |
Absolute addressing is only used with
the ACALL and AJMP instructions. |
| |
ACALL - subroutine call (2 byte instruction)
|
| |
AJMP - unconditional jump (2 byte instruction)
|
| |
These instructions allow you to move
to any instruction within the same 2K of memory. |
| |
We will look at the AJMP instruction
only (at a later date, when we begin dealing with subroutines we will
deal with the ACALL instruction). |
| |
|
| |
The operation of the AJMP instruction
is detailed below: |
| |
AJMP address
(PC) <- (PC) + 2
(PC10-PC0) <- address10 - address0
|
| |
|
| |
Note that only the eleven least
significant bits of the PC are altered. The five most significant bits
remain the same. This means the AJMP will only allow you to jump to a
location in the same 2K page as the instruction directly after the jump. |
| |
|
| |
For example: |
| |
|
| |
If the label THERE represents an instruction at address
0F46H and the instruction AJMP THERE is in memory at locations
0900H and 0901H, the assembler will encode the instruction as
|
| |
11100001 1st byte (A10 - A8 + opcode)
01000110 2nd byte (A7 - A0)
|
| |
The underlined bits are the low-order 11 bits of the
destination address, 0F46H = 0000111101000110B. The upper five
bits in the program counter will not change when this instruction
executes. Note that both the AJMP instruction and the destination are
within the 2K page bounded by 0800H and 0FFFH, and therefore have the
upper five address bits in common.
|
| |
The 8051 Microcontroller Third Edition - I.
Scott MacKenzie
|
| |
|
| |
|
| |
|
| |
Note: it is not important to
remember the different kinds of addressing modes and which instructions
belong to which mode. It is far more important to understand how to get
data from one place to another and how to perform operations upon the
data. You will never be asked to memorise a processor's instruction
set. This will always be provided. However, as we shall see when we
start writing programs, it is important to be able to use the
instruction set. |
| |
Most of our early programs will
deal with moving data into and out of the accumulator, performing
arithmetic operations and jumping to different parts of the program. |
| |
|
| |
Complete
Instruction Set |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
Copyright (c) 2005-2006 NyCelt LLC
|