Instruction Set Summary
AJMP THERE
FIGURE 3-3
Instruction encoding for absolute addressing. (a) Memory map showing 2K pages (b) Within any 2K page, the upper five address bits are the same for the source and destination addresses. The lower 11 bits of the destination are supplied in the instruction
is in memory locations 0900H and 0901H, the assembler will encode the instruction as 11100001 - 1st byte (Al0-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 (see Figure 3-3), and therefore have the upper five address bits in common.
Absolute addressing offers the advantage of short (2-byte) instructions, but has the dis-advantages of limiting the range for the destination and providing position-dependent code.
EXAMPLE An ACALL instruction is in memory locations 1024H and 1025H. The subroutine to 3.8 which the call is directed begins in memory location 17A6H. What are the machine
language bytes for the ACALL instruction?
Solution F1H, A6H Discussion
As found in Appendix C, the encoding for the ACALL instruction is aaal000l aaaaaaaa
The low-order 11 bits of the destination address are inserted into the instruction with bits 10-8 placed in the high-order bits of the opcode and with bits 7-0 forming the second byte of the instruction. The destination address (17A6H) is shown below in binary with the low-order 11 bits identified as a group of three bits (10-8) and a group of eight bits (7-F).
00010111 10100110 = 17A6H ... aaa a aaa aa aa
The task is simply to correctly position the 11 bits from the destination address into the in-struction bytes. This positioning is illustrated as follows:
lll1000l 10100ll0 = 0F1A6H aaa ... aaaaaaaa
Note: Absolute addressing can only be used if the high-order five bits are the same in both the source and destination addresses. It is this property that identifies the source and desti-nation addresses as falling within the same 2K page.
3.2.7 Long Addressing
Long addressing is used only with the LCALL and LJMP instructions. These 3-byte instructions include a full 16-bit destination address as bytes 2 and 3 of the instruction. (See Figure 3-1g.) The advantage is that the full 64K code space may be used, but the disadvantage is that the
instructions are three bytes long and are position-dependent. Position-dependence is a dis-advantage because the program cannot execute at different addresses. If, for example, a program begins at 2000H and an instruction such as LJMP 2040H appears, then the program cannot be moved to, say, 4000H. The LJMP instruction would still jump to 2040H, which is not the correct location after the program has been moved.
EXAMPLE What are the machine language bytes for the following instruction?
3.9 LJMP 8AF2H
Solution 02H, 8AH, F2H Discussion
As given in Appendix C, the LJMP instruction is three bytes long with the opcode (02H) in the first byte and the 16-bit destination address in bytes 2 and 3. The high byte of the des-tination address (8AH) is in byte 2, and the low byte (0F2H) is in byte 3.
3.2.8 Indexed Addressing
Indexed addressing uses a base register (either the program counter or the data pointer) and an offset (the accumulator) in forming the effective address for a JMP or MOVC instruc-tion. (See Figure 3-1h.) Jump tables or look-up tables are easily created using indexed ad-dressing. Examples are provided in Appendix C for the MOVC A,@A+<base-reg> and JMP @A+ DPTR instructions.
EXAMPLE What is the opcode for the following instruction?
3.10 MOVC A,@A+DPTR
Solution 93H
Discussion
The answer is found simply by looking up the MOVC instruction in Appendix C. The in-struction is only one byte long, with the opcode specifying both the operation and the ad-dressing mode. This instruction moves a byte of data from code memory to the accumulator.
The address in code memory is found by adding the index (the present state of the accu-mulator) to the base register (the data pointer). When the instruction finishes executing, the index is lost because it is overwritten with the value moved from code memory.
3.3
INSTRUCTION TYPESThe 8051 instructions are divided among five functional groups:
Arithmetic
Logical
Data transfer
Boolean variable
Program branching
Appendix A provides a quick reference chart showing all the 8051 instructions by func-tional grouping. Once you are familiar with the instruction set, this chart should prove a handy and quick source of reference. We continue by examining instructions in each func-tional grouping from Appendix A.
3.3.1 Arithmetic Instructions
The arithmetic instructions are grouped together in Appendix A. Since four addressing modes are possible, the ADD A instruction can be written in different ways:
ADD A,7PH (direct addressing) ADD A,@R0 (indirect addressing) ADD A,R7 (register addressing) ADD A,#35H (immediate addressing)
All arithmetic instructions execute one machine cycle except the INC DPTR instruction (two machine cycles) and the MUL AB and DIV AB instructions (four machine cycles).
(Note that one machine cycle takes 1 µs if the 8051 is operating from a 12 MHz clock.) EXAMPLE The accumulator contains 63H, R3 contains 23H, and the PSW contains 00H. (a) What is 3.11 the hexadecimal content of the accumulator and the PSW after execution of the following
instruction?
ADD A,R3
(b) What is the content of the accumulator in decimal after execution of this instruction?
Solution
(a) ACC = 86H, PSW = 05H. (b) Decimal content of ACC = ? (see discussion).
Discussion
On the surface, this example seems straightforward: Given two values, add them and ob-tain the sum. However, there are some interesting conceptual issues that are important to understand. Let us begin by expressing the initial values of the ACC and R3 in decimal.
By the usual method of conversion to decimal, A = 63H = 01100011B = 9910 and R3 = 23H = 00100011B = 3510. So, the result of the addition is 9910 + 3510 = 13410. However, there is a problem. If we assume that a two's-complement signed notation is used, the largest positive number that can be expressed in 8 bits is +12710. If an unsigned notation is used, the largest possible 8-bit value is +25510and, in this case, the final result of 13410is perfectly OK.
Of course, the 8051 CPU has no special knowledge of whether the data are signed binary, unsigned binary, binary-coded decimal, ASCII, etc. Only you—the programmer—
knows for sure. The mechanism to manage different formats of data is provided through the status bits in the PSW. To illustrate this, the addition is worked out below in binary.
11...11.
01100011 (ACC = 63H)
+00100011 (R3 = 23H)
10000110 (result stored in ACC = 86H)
The result is 10000110B = 86H. Note above that carries occurred out of bits 0, 1, 5, and 6. Carries did not occur out of bits 2, 3, 4, and 7. Because there was no carry out of bit 7, the C (carry) bit in the PSW is not set after the addition.
As for the OV (overflow) bit, the following description appears in Appendix C for the ADD instruction: "the OV bit is set if there is a carry out of bit 6 but not out of bit 7, or a carry out of bit 7 but not out of bit 6; otherwise OV is cleared." This is a formal way of saying, "the OV bit is set if the result is out of range for 8-bit signed numbers." In this example, there was a carry out of bit 6 but not out of bit 7; therefore, the OV bit is set.
This makes sense if the data are signed, because the allowable range is -12810to +12710
and the result of 9910+ 3510is "out of range."
From the 8051 CPU's perspective, it is also possible that the data are binary-coded decimal (only the programmer knows for sure!), and it will set or clear the auxiliary carry bit accordingly. Since a carry did not occur out of bit 3, the AC bit is cleared.
Finally, the P bit in the PSW is set or cleared to establish even parity with the accu-mulator. Because the result in the ACC has three bits equal to one, the P bit is set, bringing the total to four - an even number. The final value in the PSW is 00000101B = 05H. Only the OV and P bits are set; the other bits are cleared (see Table 2-3).
The second question in this example is, "What is the content of the accumulator in decimal after execution of this instruction?" And it is here that we delve into the important concept of the meaning or interpretation of the data on which a CPU like the 8051 operates.
Because the original problem did not indicate a format or representation for the original data, we cannot answer the question with certainty, hence the "?" in the solution. There are, however, at least two possible answers. First, if we assume the original data are in unsigned binary notation, then the result is "in range" (because C = 0) and the answer is 13410. Sec-ond, if we assume the data are in signed binary notation using twos-complement notation, then the correct answer is "out of range" (because OV = 1). The important point is that the meaning or representation scheme in effect is not a characteristic of the CPU, but, rather, it is determined by the way the data are managed by the software.
EXAMPLE Illustrate an instruction sequence to subtract the content of R6 from R7 and leave the 3.12 result in R7.
For both addition and subtraction, the accumulator holds one of the values for the operation.
So, the first instruction above moves one of the bytes to the accumulator to prepare for the operation. The second instruction clears the carry flag in the program status word. This is required because the only form of the subtract instruction is SUBB
—
subtract with borrow.The operation subtracts from the accumulator the source byte and the carry bit. For subtract operations, the carry bit serves as a "borrow" bit. If the state of the carry bit is unknown, it must be explicitly cleared using CLR C before executing SUBB. The third instruction per-forms the subtraction, leaving the result in the accumulator. The fourth instruction moves the result into R7.
The 8051 provides powerful addressing of its internal memory space. Any location can be incremented or decremented using direct addressing without going through the ac-cumulator. For example, if internal RAM location 7FH contains 40H, then the instruction
INC 7FH
increments this value, leaving 41H in location 7FH.
EXAMPLE Suppose the 8051 did not have an instruction to directly increment an internal RAM 3.13 location. How could this operation be achieved?
Solution
MOVE A,direct INC A
M O V d i r e c t , A Discussion
The first instruction moves a byte of data from an internal RAM location to the accumula-tor. The second instruction increments the value read (which is now in the accumulator), and the third instruction writes the result back to internal RAM. Not only is this instruction sequence longer and slower than the single-instruction equivalent (INC direct), the previous value of the accumulator is lost.
One of the INC instructions operates on the 16-bit data pointer. Since the data pointer generates 16-bit addresses for external memory, incrementing it in one operation is a useful feature. Unfortunately, a decrement data pointer instruction is not provided and requires a sequence of instructions such as the following:
DEC DPL ;DECREMENT LOW-BYTE OF DPTR