In Section 2.1 we look at the inside of the 8051. We demonstrate some of the widely used registers of the 8051 with simple instructions such as MOV and ADD. In Section 2.2 we examine. Assembly language and machine language programming and define terms such as mnemonics, opcode, operand, etc. The process of assembling and creating a ready-to-run program for the 8051 is discussed in Section 2.3. Step-by-step execution of an 8051 program and the role of the program counter are examined in Section 2.4. In Section 2.5 we look at some widely used Assembly language directives, pseudocode, and data types related to the 8051. In Section 2.6 we discuss the flag bits and how they are affected by arithmetic instructions. Allocation of RAM memory inside the 8051 plus the stack and register banks of the 8051 are discussed in Section 2.7.
SECTION 2.1: INSIDE THE 8051
In this section we examine the major registers of the 8051 and show their use with the simple instructions MOV and ADD.
In the CPU, registers are used to store
information temporarily. That information could be a byte of data to be processed, or an address pointing to the data to be fetched. The vast majority of 8051 registers are 8-bit registers. In the 8051 there is only one data type: 8 bits. The 8 bits of a register are shown in the diagram from the MSB (most significant bit) D7 to the LSB (least significant bit) DO. With an 8-bit data type, any data larger than 8 bits must be broken into 8-bit chunks before it is processed. Since there are a large number of registers in the 8051, we will concentrate on some of the widely used general-purpose registers and cover special registers in future chapters. See
Appendix A.2 for a complete list of 8051 registers.
Figure 2-1 (a). Some 8-bit Registers of the 8051
Figure 2-1 (b). Some 8051 16-bit Registers
The most widely used registers of the 8051 are A (accumulator), B, RO, Rl, R2, R3, R4, R5, R6, R7, DPTR (data pointer), and PC (program counter). All of the above registers are 8-bits, except DPTR and the program counter. The accumulator, register A, is used for all arithmetic and logic instructions. To understand the use of these registers, we will show them in the context of two simple instructions, MOV and ADD.
Simply stated, the MOV instruction copies data from one location to another. It has the following format:
MOV destination,source ;copy source to dest.
This instruction tells the CPU to move (in reality, copy) the source operand to the destination operand. For example, the instruction “MOV A, RO” copies the contents of register RO to register A. After this instruction is executed, register A will have the same value as register RO. The MOV instruction does not affect the source operand. The following program first loads register A with value 55H (that is 55 in hex), then moves this value around to various registers inside the CPU. Notice the “#” in the instruction. This signifies that it is a value. The importance of this will be discussed soon.
MOV A,#55H ;load value 55H into reg. A
MOV RO,A ;copy contents of A into RO
MOV R1,A ,-copy contents of A into Rl
MOV R2,A ;copy contents of A into R2
MOV R3,#95H ;load value 95H into R3
MOV A,R3 /copy contents of R3 into A
When programming the 8051 microcontroller, the following points should be noted: 1. Values can be loaded directly into any of registers A, B, or RO – R7. However,
to indicate that it is an immediate value it must be preceded with a pound sign
(#). This is shown next.
MOV A,#23H ;load 23H into A (A=23H)
MOV RO,#12H ;load 12H into RO (RO=12H)
MOV R1,#1FH ;load 1FH into Rl (R1=1FH)
MOV R2,#2BH ;load 2BH into R2 (R2=2BH)
MOV B,#3CH ;load 3CH into B (B=3CH)
MOV R7,#9DH ;load 9DH into R7 (R7=9DH)
MOV R5,#OF9H ;load F9H into R5 (R5=F9H)
MOV R6,#12 ,-load 12 decimal (OCH)
,-into reg. R6 (R6 = OCH)
Notice in instruction “MOV R5 , #0F9H” that a 0 is used between the # and F to indicate that F is a hex number and not a letter. In other words “MOV R5 , #F9H” will cause an error.
If values 0 to F are moved into an 8-bit register, the rest of the bits are assumed
to be all zeros. For example, in “MOV A, #5″ the result will be A = 05; that
is, A = 00000101 in binary.
Moving a value that is too large into a register will cause an error.
MOV A,#7F2H ;ILLEGAL: 7F2H > 8 bits (FFH) MOV R2,#456 ;ILLEGAL: 456 > 255 decimal (FFH)
4. A value to be loaded into a register must be preceded with a pound sign (#).
Otherwise it means to load from a memory location. For example “MOV
A, 17H” means to move into A the value held in memory location 17H, which
could have any value. In order to load the value 17H into the accumulator we
must write “MOV A, #17H” with the # preceding the number. Notice that the
absence of the pound sign will not cause an error by the assembler since it is a
valid instruction. However, the result would not be what the programmer
intended. This is a common error for beginning programmers in the 8051.
The ADD instruction has the following format:
ADD A,source ;ADD the source operand
;to the accumulator
The ADD instruction tells the CPU to add the source byte to register A and put the result in register A. To add two numbers such as 25H and 34H, each can be moved to a register and then added together:
MOV A,#25H /load 25H into A MOV R2,#34H ;load 34H into R2 ADD A,R2 /add R2 to accumulator
; (A = A + R2)
Executing the. program above results in A – 59H (25H + 34H = 59H) and R2 = 34H. Notice that the content of R2 does not change. The program above can be written in many ways, depending on the registers used. Another way might be:
MOV R5,#25H ;load 25H into R5 (R5=25H) MOV R7,#34H ;load 34H into R7 (R7=34H) MOV A,#0 /load 0 into A (A=0,clear A) ADD A,R5 ;add to A content of R5
; where A = A + R5 ADD A,R7 /add to A content of R7
; where A = A + R7
The program above results in A = 59H. There are always many ways to write the same program. One question that might come to mind after looking at the program above, is whether it is necessary to move both data items into registers before adding them together. The answer is no, it is not necessary. Look at the following variation of the same program:
MOV A,#25H ;load one operand into A (A=25H)
ADD A,#34H ;add the second operand 34H to A
In the above case, while one register contained one value, the second value followed the instruction as an operand. This is called an immediate operand. The examples shown so far for the ADD instruction indicate that the source operand can be either a register or immediate data, but the destination must always be register A, the accumulator. In other words, an instruction such as “ADD R2 , #12H” is invalid since register A (accumulator) must be involved in any arithmetic operation. Notice that “ADD R4, A” is also invalid for the reason that A must be the destination of any arithmetic operation. To put it simply: In the 8051, register A must be involved and be the destination for all arithmetic operations. The foregoing discussion explains why register A is referred to as the accumulator. The format for Assembly language instructions, descriptions of their use, and a listing of legal operand types are provided in Appendix A. 1.
There are two 16-bit registers in the 8051: PC (program counter) and DPTR (data pointer). The importance and use of the program counter are covered in Section 2.3. The DPTR register is used in accessing data and is discussed in Chapter 5 where addressing modes are covered.