8051内部的CPU是一个字长为二进制8位的中央处理单元,也就是说它对数据的处理是按字节为单位进行的。与微型计算机CPU类似,8051内部的CPU也是由运算器(ALU)、控制器(定时控制部件等)和专用寄存器组3个部分电路组成的。
8051的算术逻辑部件ALU是一个性能极强的运算器,它既可以进行加、减、乘、除四则运算,也可以进行与、或、非、异或等逻辑运算,有数据传送、移位、判断和程序转移等功能,同时还有独特的位处理功能,如置位、清零、取反、转移、检测等。8051的ALU为用户提供了丰富的指令系统和极快的指令执行速度,如振荡器频率为12MHz的情况下,大部分指令的执行时间为lμs,乘法指令可达4μs。
8051的ALU由一个加法器、两个8位暂存器(TMPl与TMP2)和一个性能卓越的布尔处理器组成。虽然TMPl和TMP2对用户并不开放,但可用来为加法器和布尔处理器暂存两个8位二进制操作数。
归纳其特点有如下一些。
(1)在B寄存器的配合下,能完成乘法与除法操作。
(2)可进行多种内容交换操作。
(3)能作比较判断操作。
(4)有强的位操作功能。
定时控制部件起着控制器作用,由定时控制逻辑、指令寄存器IR、指令译码器ID和振荡器OSC等电路组成。指令寄存器IR用于存放从程序存储器中取出的指令码,指令译码器用于对IR中的指令码译码,根据不同指令由定时和控制逻辑在OSC配合下产生相应的控制信号,送到存储器、运算器或I/O接口电路,以完成相应指令的执行。
图2-4 HMOS型单片机内部振荡器OSC
|
专用寄存器组主要用来指示当前要执行指令的内存地址、存放操作数和指示指令执行后的状态等。它是任何一台计算机的CPU不可缺少的组成部件,其寄存器的数目因计算机型号的不同而异。专用寄存器组主要包括程序计数器PC、累加器A、程序状态寄存器PSW、堆栈指示器SP、数据指针DPTR和通用寄存器B等。
程序计数器(Program Counter,PC)是一个二进制16位的程序地址寄存器,专门用来存放下一条需要执行的指令的内存地址,能自动加1。CPU执行指令时,它是先根据程序计数器PC中的地址从存储器中取出当前需要执行的指令码,并把它送给控制器分析执行的,随后程序计数器PC中的地址码自动加1,以便为CPU取下一个需要执行的指令码作准备。当下一个指令码取出执行后,PC又自动加1。这样,程序计数器PC一次次加1,指令就被一条条执行。所以需要执行的程序的机器码必须在程序执行前预先一条条地按序放到程序存储器中,并将程序计数器PC设置成程序第一条指令的内存地址。
8051程序计数器PC由16个触发器构成,故它的编码范围为0000H~FFFFH,共64KB。这就是说,8051对程序存储器的寻址范围为64KB。如果要为8051配置大于64KB的程序存储器,就必须在制造8051器件时加长程序计数器的位数。在实际应用中,64KB的程序存储器就已足够。
累加器A(accumulator)又记作ACC,是一个具有特殊用途的二进制8位寄存器,专门用来存放操作数或运算结果。在CPU执行某种运算前,两个操作数中的一个通常应放在累加器A中,运算完成后累加器A中便可得到运算结果。例如,在如下的加法程序中:
MOV A,#03H;A←3
ADD A,#05H;A←A+05H
第一条指令是把加数3预先送入累加器A,为第二条加法指令的执行作了准备。第二条指令执行前,累加器A中为加数3,执行后变为两数之和8。
通用寄存器B(General Purpose Register)是专门为乘法或除法设置的寄存器,也是一个二进制8位寄存器,由8个触发器组成。该寄存器在乘法或除法前,用来存放乘数或除数。在乘法或除法完成后用于存放乘积的高8位或除法的余数。以乘法运算为例加以说明:
MOV A,#05H;A←5
MOV B,#03H;B←3
MUL AB ;BA←A×B=5×3
上述程序中,前面两条是传送指令,是进行乘法前的准备指令。因此,乘法指令执行前累加器A和通用寄存器B中分别存放了两个乘数,乘法指令执行完后,积的高8位自动在B中形成,积的低8位自动在A中形成。
程序状态字寄存器(Program Status Word,PSW)是一个8位标志寄存器,用来存放指令执行后的有关状态。PSW中各位状态通常是在指令执行过程中自动形成的,但也可以由用户根据需要采用传送指令加以改变。其各标志位定义如图2-5所示。
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
C |
AC |
F0 |
RS1 |
RS0 |
OV |
F1 |
P |
图2-5 各标志位定义
其中,PSW.7(D7)为最高位,PSW.0(D0)为最低位。各位含义如下。
· 进位标志位C(carry):用于表示加减运算过程中累加器A的最高位有无进位或借位。在加法运算时,若累加器的最高位A7有进位,则C=1,否则C=0;在减法运算时,若A7有了借位,则C=1,否则C=0。此外,CPU在进行移位操作时也会影响这个标志位。
· 辅助进位位AC(Auxiliary Carry):用于表示加减运算时低4位(即A3)有无向高4位(即A4)进位或借位。若AC=0,则表示加减过程中A3没有向A4进位或借位;若AC=1,则表示加减过程中A3向A4有了进位或借位。
· 用户标志位F0(flag zero):F0标志位的状态通常不是机器在执行指令过程中自动形成的,是由用户根据程序执行的需要通过传送指令确定的。该标志位状态一经设定,用户程序直接检测,以决定用户程序的流向。
· 寄存器选择位RSl和RS0:8051共有8个8位工作寄存器,分别命名为R0~R7。工作寄存器R0~R7常常被用户用来进行程序设计,但它在RAM中的实际物理地址是可以根据需要选定的。RS1和RS0就是为了这个目的提供给用户使用的,用户通过改变RS1和RS0的状态可以方便地决定R0~R7的实际物理地址。工作寄存器R0~R7的物理地址和RS1、RS0之间的关系如表2-1所示。
表2-1 RS1、RS0对工作寄存器的选择
RS1 |
RS0 |
R0~R7的组号 |
R0~R7的物理地址 |
0 0 1 1 |
0 1 0 1 |
0 1 2 3 |
00H~07H 08H~0FH 10H~17H 18H~lFH |
采用8051或8031做成的单片机控制系统,开机后的RS1和RS0总是为零状态,故R0~R7的物理地址为00H~07H,即R0的地址为00H,R1的地址为01H,……,R7的地址为07H。但若机器执行如下指令:
MOVPSW,#08H;
则RS1、RS0显然为01B,故R0~R7的物理地址变为08H~0FH。因此,用户利用这种方法可以很方便地达到保护R0~R7中的数据的目的,这对用户的程序设计是非常有利的。
· 溢出标志位OV(overflow):指示运算过程中是否发生了溢出,由机器执行指令过程中自动形成。若机器在执行运算指令过程中,累加器A中的运算结果超出了8位数能表示的范围,即-128~+127,则OV标志自动置1;否则OV=0,因此,人们根据执行运算指令后的OV状态就可判断累加器A中的结果是否正确。
· 奇偶标志位P(parity):PSW.1为无定义位,用户也可不使用。PSW.0为奇偶标志位P,用于指示运算结果中“1”的个数的奇偶性。若P=1,则累加器A中1的个数为奇数;若P=0,则累加器A中的“1”的个数为偶数。
堆栈指针(Stack Pointer,SP)是一个8位寄存器,能自动加1或减l,专门用来存放堆栈的栈顶地址。
人们在堆放货物时,总是把先入栈的货物堆放在下面,后入栈的货物堆放在上面,一层一层向上堆。取货时的顺序和堆货顺序正好相反,最后入栈的货物最先被取走,最先入栈的货物最后被取走。因此,货栈的堆货和取货符合“先进后出”或“后进先出”的规律。
计算机中的堆栈类似于商业中的货栈,是一个能按“先进后出”或“后进先出”规则存取数据的RAM区域。这个区域是可大可小的,常称为堆栈区。8051片内RAM共有128个字节,地址范围为00H~7FH,这个区域中的任何子域都可以用作堆栈区,即作为堆栈来用。堆栈有栈顶和栈底之分,栈底由栈底地址标识,栈顶由栈顶地址指示。栈底地址是固定不变的,它决定了堆栈在RAM中的物理位置;栈顶地址始终在SP中,即由SP指示,是可以改变的,它决定堆栈中是否存放有数据。因此,当堆栈中无数据时,栈顶地址必定与栈底地址重合,即SP中一定是栈底地址;堆栈中存放的数据越多,SP中的栈顶地址比栈底地址越大。这就是说,SP就好像是一个地址指针,始终指示着堆栈中最上面的那个数据。通常堆栈由如下指令设定:
MOV SP, #data ;SP←data
若把指令中的data用70H替代,则机器执行这条指令后就设定了堆栈的栈底地址70H。此时,堆栈中尚未压入数据,即堆栈是空的,故SP中的70H地址也是堆栈的栈顶地址,如图2-6(a)所示。堆栈中的数据是由PUSH指令压入和POP指令弹出的,PUSH指令使SP中的内容加1,POP指令则使SP减1。例如,如下程序可以把数据50H压入堆栈:
MOV A, #50H;A←50H
PUSH ACC ;SP←SP+1,(SP)←ACC
第一条指令可以把50H送入累加器A;第二条指令先使SP加1变为71H,然后把累加器A中的50H取出来按SP(即71H)压入堆栈,如图2-6(b)所示。如果要继续向堆栈中压入数据,则可继续使用PUSH指令;如果要从堆栈中弹出数据,可使用POP指令。这些将在指令系统中详细介绍。
(a)没有压入数时的堆栈 (b)压入一个数时的堆栈
图2-6 堆栈示意图
由于堆栈区在程序中没有标识,因此程序设计人员在进行程序设计时应给可能的堆栈区让出若干存储单元,这些单元是禁止用传送指令存放数据的,只能由PUSH和POP指令访问它们。
数据指针(Data Pointer,DPTR)是一个16位的寄存器,由两个8位寄存器DPH和DPL拼装而成,其中DPH为DPTR的高8位,DPL为DPTR的低8位。DPTR可以用来存放片内ROM的地址,也可以用来存放片外RAM和片外ROM的地址。例如,设片外RAM的2000H单元中有一个数X,若要把它取到累加器A,则可采用如下程序:
MOV DPTR,#2000H;DPTR←2000H
MOVX A,@DPTR ;A←X
第一条指令执行后,机器自动把2000H装入DPTR;第二条指令执行时,机器自动把DPTR中的2000H作为外部RAM的地址,并根据这个地址把X取到累加器A中。其中,第二条指令操作码助记符中的X指示DPTR中的2000H是外部RAM的地址,而不是外部ROM的地址,这将在第3章指令系统中深入讨论。