第3章 51单片机指令系统 51单片机CPU的指令系统是其所能执行的全部指令的集合,一条指令完成一个独立的操作,多条指令组成可执行程序,完成一项或多项功能(任务)。本章介绍51单片机的CPU指令系统,内容包括指令的格式、指令助记符、伪指令、由指令组成的可执行应用程序等。 3.151单片机CPU指令系统概述 51单片机CPU共有111条指令,它们是由表明操作性质的指令助记符结合对操作数的不同寻址方式形成的,该指令系统具有多种操作功能,按其功能可以归纳为4类: 数据传送类指令(29条); 算术、逻辑运算类指令(24条+24条); 控制转移类指令(17条); 位操作、位控制转移类指令(17条)。 3.1.1指令的格式 51单片机的CPU指令格式的统一表现形式为 操作码+[操作数] 操作码和操作数构成指令机器码,它是CPU能够执行的指令,在51单片机系统中,指令机器码存放于ROM区域,其存放格式如图31所示。 51单片机的CPU指令系统中有无操作数(操作码A)、单操作数(操作码B+操作数B)、双操作数(操作码C+操作数C1+操作数C2)3种格式的指令,按指令占存储器字节数统计单字节指令有49条、双字节指令有45条、三字节指令有17条,按指令占用CPU(执行)时间统计单机器周期指令有64条、双机器周期指令有45条、四机器周期指令有2条。 图31CPU指令机器码在ROM中存放顺序 3.1.2指令操作码助记符以及操作数表示符号 51单片机CPU指令按功能划分为4类,其操作码所使用的助记符如表31所示,其指令格式中常用的操作数表示符号以及含义如表32所示。 表3151单片机的CPU指令操作码助记符 指 令 功 能 助记符 数据传送类指令 MOV、MOVX、MOVC、PUSH、POP、HCX、XCHD、SWAP 算术、逻辑运算类指令 算术: ADD、ADDC、INC、DA、SUBB、DEC、MUL、DIV 逻辑: ANL、ORL、XRL、CPL、CLR、RL、RR、RLC、RRC 控制转移类指令 LJMP、AJMP、SJMP、LCALL、ACALL、RET、RETI、JZ、JNZ、CJNE、DJNZ、NOP 位操作、控制转移类指令 CLR、SETB、ANL、ORL、CPL、MOV、JC、JNC、JB、JNB、JBC 表3251单片机的CPU指令中操作数表示符号及含义 表 示 符 号 含义 Rn 表示工作寄存器,n=0~7,4组,由PSW中RS1、RS0确定组号 Ri 表示间址寄存器,i=0、1,只有R0和R1可作间址寄存器使用 #data 表示 8 位立即数,取值范围00H~0FFH,代表常量,存放在ROM程序存储区 #data16 表示 16 位立即数,取值范围0000H~0FFFFH,代表常量,存放在ROM程序存储区 direct 表示 8 位芯片内RAM直接地址,地址范围256B,取值范围00H~0FFH addr16 表示 16 位芯片内、外存储器直接地址,地址范围64KB,A0~A15 addr11 表示 11 位芯片内、外存储器直接地址,地址范围2KB,A0~A10 bit 表示位地址,RAM位编址区00H~7FH,SFR可寻址位,取值范围00H~0FFH rel 表示地址偏移量,地址范围256B,其数值为8位有符号数据,取值区域-128 ~+127 @ 表示间接寻址,@R0,@R1,@A+DPTR、PC / 表示取非位操作,/ bit =bit 3.1.3寻址方式 51单片机CPU指令系统有7种寻址方式(寻找操作数或操作数所在地址的方式),7种寻址方式的名称以及寻找操作数所对应的存储器地址空间如表33所示。 表3351单片机CPU指令寻址方式 寻 址 方 式 存储器地址空间—操作数存放空间 立即寻址 立即数(#data),ROM程序存储空间 直接寻址 RAM区域(direct),芯片内RAM低128B、特殊功能寄存器SFR 寄存器寻址 工作寄存器 R0~R7、A、B、DPTR等特殊功能寄存器SFR 寄存器间接寻址 芯片内、外RAM空间,针对间接寄存器@R0、@R1、SP、DPTR 变址寻址 ROM程序存储空间,针对变址基址DPTR、PC寄存器,@A+PC、@A+DPTR 相对寻址 ROM程序存储空间,相对PC寄存器(PC+rel),rel偏移量范围为-128~+127B 位寻址 芯片内RAM(20H~2FH)位寻址空间和可位寻址的特殊功能寄存器SFR位地址,针对位操作 51单片机CPU指令系统的7种寻址方式针对CPU中的寄存器、机器内部RAM和ROM,以及机器外部的RAM和ROM数据存储区域,由于51单片机的输入/输出(I/O)接口地址采用内部存储器RAM映像方式,其地址区域为80H~FFH,即特殊功能寄存器SFR地址区域,因此,所有适合操作内部存储器RAM的寻址方式都适合输入/输出(I/O)接口访问的操作。 51单片机的多种寻址方式可方便地从某一地址处得到数据,或者将数据传送到另外一地址处,51单片机CPU的指令系统通过各种寻址方式能实现的数据流动(CPU读或存数据)方向如图32所示。 图32CPU指令系统应用各种寻址方式使数据流动的方向图 由图32可知,在ROM中存储的立即数可以传送到RAM、累加器A、间接寄存器R0和R1指示的地址区域; CPU中的寄存器(RAM高128B处的SFR)以及RAM地址区域中的数据可以通过各种寻址方式相互传送。 3.2数据传送类指令 51单片机CPU的数据传送类指令是将数据从某一地址处取出传送到另外一个地址中,数据传送类指令的功能包括存储器之间、寄存器之间、存储器和寄存器之间、字节交换、堆栈操作、输入/输出操作等数据传送,并有多种寻址方式实现数据的传送。 3.2.1数据传送指令 51单片机CPU共有29条数据传送指令,这些指令的机器码、助记符、完成的功能、影响程序状态字PSW的标志位、占用存储器字节数、CPU执行指令所用时间(机器周期)等如表34所示。 表3451单片机CPU数据传送指令表 机器码 助记符 操作码 操作数 功能 影响PSW标志位 CY AC OV P 字节数 机器周期 E8~EF MOV A,Rn A←Rn(n=0~7) × × × √ 1 1 E5 MOV A,direct A←(direct) × × × √ 2 1 E6、E7 MOV A,@Ri A←(Ri)(i=0,1) × × × √ 1 1 74 MOV A,#data A←data × × × √ 2 1 F8~FF MOV Rn,A Rn←A(n=0~7) × × × × 1 1 A8~AF MOV Rn,direct Rn←(direct)(n=0~7) × × × × 2 2 78~7F MOV Rn,#data Rn←data(n=0~7) × × × × 2 1 F5 MOV direct,A (direct)←A × × × × 2 1 88~8F MOV direct,Rn (direct)←Rn(n=0~7) × × × × 2 2 85 MOV direct1,direct2 (direct1)←(direct2) × × × × 3 2 86、87 MOV direct,@Ri (direct)←(Ri)(i=0,1) × × × × 2 2 75 MOV direct,#data (direct)←data × × × × 3 2 F6、F7 MOV @Ri,A (Ri)←A(i=0,1) × × × × 1 1 A6、A7 MOV @Ri,direct (Ri)←(direct)(i=0,1) × × × × 2 2 76、77 MOV @Ri,#data (Ri)←data(i=0,1) × × × × 2 1 90 MOV DPTR,#data16 DPTR←data16 × × × × 3 2 E2、E3 MOVX A,@Ri A←(Ri)(i=0,1) × × × √ 1 2 E0 MOVX A,@DPTR A←(DPTR) × × × √ 1 2 F2、F3 MOVX @Ri,A (Ri)←A(i=0,1) × × × × 1 2 F0 MOVX @DPTR,A (DPTR)←A × × × × 1 2 93 MOVC A,@A+DPTR A←(A+DPTR) × × × √ 1 2 83 MOVC A,@A+PC PC←PC+1,A←(A+PC) × × × √ 1 2 C0 PUSH direct SP←SP+1,(SP)←(direct) × × × × 2 2 D0 POP direct (direct)←(SP),SP←SP - 1 × × × × 2 2 C8~CF XCH A,Rn ARn(n=0~7) × × × √ 1 1 C5 XCH A,direct A(direct) × × × √ 2 1 C6、C7 XCH A,@Ri A(Ri)(i=0,1) × × × √ 1 1 D6、D7 XCHD A,@Ri A0~A3 (Ri)0~(Ri)3(i=0,1) × × × √ 1 1 C4 SWAP A A0~A3 A4~A7 × × × √ 1 1 3.2.2数据传送指令详解 数据传送指令包括51单片机内部数据传送指令MOV、CPU与外部数据交换数据指令MOVX、读取程序存储器数据指令MOVC、其他数据交换指令。 1. 机器内部数据传送指令 (1) MOVA,Rn指令 指令机器码: 1 1 1 01 r r r 指令实现的操作: 将工作寄存器Rn(R0~R7)之一的内容送入累加器A中,指令机器码(CPU可执行代码)中r r r 3位数据000~111表示R0~R7,该指令影响程序状态字PSW的P标志位,P表示送到累加器A中数据的奇偶性,累加器A中奇数个1,P=1,否则P=0。 (2) MOVA,direct 指令 指令机器码: 1 1 1 00 1 0 1 direct 指令实现的操作: 取出片内RAM直接地址单元direct中的内容送入累加器A中,该指令影响程序状态字PSW的P标志位。 (3) MOVA,@Ri指令 指令机器码: 1 1 1 00 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为片内RAM地址(通过Ri间接指示RAM地址),取出Ri指示的RAM地址中的内容送入累加器A中,指令机器码中i为一位数据0~1表示R0、R1,该指令影响程序状态字PSW的P标志位。 (4) MOVA,#data 指令 指令机器码: 1 1 1 00 1 0 1 #data 指令实现的操作: 将ROM中的立即数送入累加器A中,该指令影响程序状态字PSW的P标志位。 (5) MOVRn,A指令 指令机器码: 1 1 1 11 r r r 指令实现的操作: 将累加器A中的数据送入工作寄存器Rn(R0~R7)之一中,指令机器码中r r r 3位数据000~111表示R0~R7。 (6) MOVRn,direct指令 指令机器码: 1 0 1 01 r r r direct 指令实现的操作: 取出片内RAM直接地址单元direct中的内容送入工作寄存器Rn(R0~R7)之一中,指令机器码中r r r 3位数据000~111表示R0~R7。 (7) MOVRn,#data指令 指令机器码: 0 1 1 11 r r r #data 指令实现的操作: 将ROM中的立即数送入工作寄存器Rn(R0~R7)之一中。 (8) MOVdirect,A指令 指令机器码: 1 1 1 10 1 0 1 direct 指令实现的操作: 将累加器A中的数据送入片内RAM直接地址单元direct中。 (9) MOVdirect,Rn 指令 指令机器码: 1 0 0 01 r r r direct 指令实现的操作: 将工作寄存器Rn(R0~R7)之一中的数据送入RAM直接地址单元direct中。 (10) MOVdirect1,direct2指令 指令机器码: 1 0 0 00 1 0 1 direct2(源) direct1(目的) 指令实现的操作: 取出片内RAM直接地址单元direct2(源地址)中的内容送入RAM直接地址单元direct1(目的地址)中。 (11) MOVdirect,@Ri指令 指令机器码: 1 0 0 00 1 1 i direct 指令实现的操作: 工作寄存器Ri之一中的数据作为片内RAM地址,取出Ri指示的RAM地址中的内容送入RAM直接地址单元direct中,指令机器码中i(0或1)表示R0、R1。 (12) MOVdirect,#data指令 指令机器码: 0 1 1 10 1 0 1 direct #data 指令实现的操作: 将ROM中的立即数送入片内RAM直接地址单元direct中。 (13) MOV@Ri,A指令 指令机器码: 1 1 1 10 1 1 i 指令实现的操作: 将累加器A中的数据送入工作寄存器Ri(R0~R1)之一中的数据作为片内RAM地址的存储单元中,指令机器码中i(0或1)表示R0、R1。 (14) MOV@Ri,direct指令 指令机器码: 0 1 0 10 1 1 i direct 指令实现的操作: 取出RAM直接地址单元direct中的数据送入工作寄存器Ri(R0~R1)之一中的数据作为片内RAM地址(间址)的存储单元中,指令机器码中i表示R0、R1。 (15) MOV@Ri,#data指令 指令机器码: 0 1 1 10 1 1 i #data 指令实现的操作: 将ROM中的立即数送入工作寄存器Ri(R0~R1)之一中的数据作为片内RAM地址(间址)的存储单元中,指令机器码中i(0或1)表示R0、R1。 (16) MOVDPTR,#data16指令 指令机器码: 1 0 0 10 0 0 0 #data高8位#data低8位 指令实现的操作: 将ROM中的16位立即数送入地址寄存器DPTR中,立即数高8位送入DPH,立即数低8位送入DPL。 2. CPU与外部存储器RAM交换数据指令 (1) MOVXA,@Ri指令 指令机器码: 1 1 1 00 0 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为外部存储器RAM地址(间接寻址范围0~0FFH),取出Ri指示的外部RAM地址中的内容送入累加器A中,指令机器码中i(0或1)表示R0、R1,该指令影响程序状态字PSW的P标志位,该操作使总线读信号RD=0。 (2) MOVXA,@DPTR指令 指令机器码: 1 1 1 00 0 0 0 指令实现的操作: DPTR寄存器的内容作为外部存储器RAM地址指针(间接寻址范围0~0FFFFH),取出DPTR中指示的外部RAM地址中的内容送入累加器A中,该指令影响程序状态字PSW的P标志位,该操作使总线读信号RD=0。 (3) MOVX@Ri,A指令 指令机器码: 1 1 1 10 0 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为外部存储器RAM地址,将累加器A中的数据送入Ri指示的外部RAM地址中(间接寻址单元),指令机器码中i(0或1)表示R0、R1,该操作使总线写信号WR=0。 (4) MOVX@DPTR,A指令 指令机器码: 1 1 1 10 0 0 0 指令实现的操作: DPTR寄存器的内容作为外部存储器RAM地址指针,将累加器A中的数据送入DPTR中指示的外部RAM地址中(间接寻址单元),该操作使总线写信号WR=0。 3. 读取程序存储器数据指令 (1) MOVCA,@ A+DPTR指令 指令机器码: 1 0 0 10 0 1 1 指令实现的操作: DPTR寄存器的内容作为程序存储器ROM的基地址,将累加器A中的内容与DPTR寄存器的内容做无符号相加,形成一个相加后的ROM指示地址(基址变址寻址),取出该ROM地址单元中的内容送入累加器A中,该指令影响程序状态字PSW的P标志位。 MOVCA,@ A+DPTR指令被称为查表指令,使用该指令时首先需要确定DPTR基址寄存器的内容,然后通过累加器A指出读取的数据相对DPTR指针所在的位置,其基址变址寻址范围为ROM的0~0FFFFH,相对基址DPTR寻址范围为0~256B。 (2) MOVCA,@ A+PC指令 指令机器码: 1 0 0 00 0 1 1 指令实现的操作: 首先将程序计数器PC的内容加1(字节),然后将PC的内容作为程序存储器ROM的基地址,将累加器A中的内容与PC的内容做无符号相加,形成一个相加后的ROM指示地址(基址变址寻址),取出该ROM地址单元中的内容送入累加器A中,该指令影响程序状态字PSW的P标志位。 MOVCA,@ A+PC指令同样也可以作为查表指令使用,但其是以PC(CPU将要执行的下一条指令的存储地址)的内容为基址的,由于PC的内容是不能通过指令修改的,而累加器A为8位寄存器,因此,该指令基址变址寻址范围为0~256B。 4. 其他数据交换指令 (1) PUSHdirect指令 指令机器码: 1 1 0 00 0 0 0 direct 指令实现的操作: 首先将堆栈指针寄存器SP的内容加1,然后将直接地址单元direct中的数据送入SP指示的地址单元中,SP指向片内RAM处,其初值为07H。 (2) POPdirect指令 指令机器码: 1 1 0 10 0 0 0 direct 指令实现的操作: 首先将堆栈指针寄存器SP指示的地址单元的内容送入直接地址单元direct中,然后将SP内容减1。 (3) XCHA,Rn指令 指令机器码: 1 1 0 01 r r r 指令实现的操作: 将工作寄存器Rn(R0~R7)之一的内容与累加器A的内容互相交换,指令机器码中r r r表示R0~R7,该指令影响程序状态字PSW的P标志位。 (4) XCHA,direct指令 指令机器码: 1 1 0 00 1 0 1 direct 指令实现的操作: 将直接地址单元direct中的内容与累加器A的内容互相交换,该指令影响程序状态字PSW的P标志位。 (5) XCHA,@Ri指令 指令机器码: 1 1 0 00 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为内部存储器RAM地址,将Ri指示的内部RAM地址(间接寻址单元)中的内容与累加器A的内容互相交换,该指令影响程序状态字PSW的P标志位。 (6) XCHDA,@Ri指令 指令机器码: 1 1 0 10 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为内部存储器RAM地址,将Ri指示的内部RAM地址(间接寻址单元)中的低4位数据内容与累加器A的低4位数据内容互相交换,它们各自的高4位数据内容不变,该指令影响程序状态字PSW的P标志位。 (7) SWAPA 指令 指令机器码: 1 1 0 00 1 0 0 指令实现的操作: 将累加器A中的高4位数据与其低4位数据互相交换,该指令影响程序状态字PSW的P标志位。 3.3算术运算类指令 51单片机的算术运算指令是实现8位二进制数据运算的,其运算包括算术加、减、乘、除、十进制调整等。 3.3.1算术运算指令 51单片机CPU有24条算术运算指令,算术运算指令的助记符、完成的功能、影响程序状态字PSW的标志位、占用存储器字节数、CPU执行指令所用时间(机器周期)等如表35所示。 表3551单片机CPU算术运算指令表 机器码 助记符 操作码 操作数 功能 影响PSW标志位 CY AC OV P 字节数 机器周期 28~2F ADD A,Rn A←A+Rn(n=0~7) √ √ √ √ 1 1 25 ADD A,direct A←A+(direct) √ √ √ √ 2 1 26、27 ADD A,@Ri A←A+(Ri)(i=0,1) √ √ √ √ 1 1 24 ADD A,#data A←A+data √ √ √ √ 2 1 38~3F ADDC A,Rn A←A+Rn+CY(n=0~7) √ √ √ √ 1 1 35 ADDC A,direct A←A+(direct)+CY √ √ √ √ 2 1 36、37 ADDC A,@Ri A←A+(Ri)+CY(i=0,1) √ √ √ √ 1 1 34 ADDC A,#data A←A+data+CY √ √ √ √ 2 1 98~9F SUBB A,Rn A←A - Rn - CY(n=0~7) √ √ √ √ 1 1 95 SUBB A,direct A←A -(direct) - CY √ √ √ √ 2 1 96、97 SUBB A,@Ri A←A -(Ri) - CY(i=0,1) √ √ √ √ 1 1 94 SUBB A,#data A←A - data - CY √ √ √ √ 2 1 04 INC A A←A+1 × × × √ 1 1 08~0F INC Rn Rn←Rn+1(n=0~7) × × × × 1 1 05 INC direct (direct)←(direct)+1 × × × × 2 1 06、07 INC @Ri (Ri)←(Ri)+1(i=0,1) × × × × 1 1 A3 INC DPTR DPTR←DPTR+1 × × × × 1 2 14 DEC A A←A - 1 × × × √ 1 1 18~1F DEC Rn Rn←Rn - 1(n=0~7) × × × × 1 1 15 DEC direct (direct)←(direct) - 1 × × × × 2 1 16、17 DEC @Ri (Ri)←(Ri) - 1(i=0,1) × × × × 1 1 A4 MUL AB BA←A × B 0 × √ √ 1 4 84 DIV AB A B←A ÷ B 0 × √ √ 1 4 D4 DA A A←BCD(A) √ √ × √ 1 1 3.3.2算术运算指令详解 51单片机CPU的算术运算指令实现了二进制数据的算术加、减、乘、除、加1、减1等操作,其大部分指令都会影响程序状态字PSW的CY、AC、OV、P标志位。 1. 算术加运算指令 (1) ADDA,Rn 指令 指令机器码: 0 0 1 01 r r r 指令实现的操作: 将工作寄存器Rn(R0~R7)之一的内容与累加器A中的内容进行8位无符号数据相加,相加结果送入累加器A中,指令机器码中r r r 3位数据000~111表示R0~R7。 该指令影响程序状态字PSW的CY、AC、OV、P标志位,当第7位相加结果有进位时CY=1; 当第3位相加结果有进位时,AC =1; 当使用该指令实现有符号数据相加运算时,OV等于第7位与第6位数据的异或,表示运算有溢出; 当送入累加器A中的运算结果有奇数个1时,P=1。 (2) ADDA,direct指令 指令机器码: 0 0 1 00 1 0 1 direct 指令实现的操作: 将直接地址单元direct中的内容与累加器A的内容进行8位无符号数据相加,相加结果送入累加器A中,该指令影响PSW的CY、AC、OV、P标志位。 (3) ADDA,@Ri指令 指令机器码: 0 0 1 00 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为内部存储器RAM地址,将Ri指示的内部RAM地址(间接寻址单元)中的数据内容与累加器A的数据内容进行8位无符号数据相加,相加结果送入累加器A中,该指令影响PSW的CY、AC、OV、P标志位。 (4) ADDA,#data指令 指令机器码: 0 0 1 00 1 0 0 #data 指令实现的操作: 将ROM中的立即数与累加器A的内容进行8位无符号数据相加,相加结果送入累加器A中,该指令影响PSW的CY、AC、OV、P标志位。 (5) ADDCA,Rn 指令 指令机器码: 0 0 1 11 r r r 指令实现的操作: 将工作寄存器Rn(R0~R7)之一的内容与累加器A中的内容以及在最低位(第0位)上与PSW的CY(进位位)进行三者数据相加,相加结果送入累加器A中,影响PSW的标志位情况与ADD指令相同。 (6) ADDCA,direct指令 指令机器码: 0 0 1 10 1 0 1 direct 指令实现的操作: 将直接地址单元direct中的内容与累加器A的内容以及在最低位上与PSW的CY位进行三者数据相加,相加结果送入累加器A中,影响PSW的标志位情况与ADD指令相同。 (7) ADDCA,@Ri指令 指令机器码: 0 0 1 10 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为内部存储器RAM地址,将Ri指示的内部RAM地址(间接寻址单元)中的数据内容与累加器A的数据内容以及在最低位上与PSW的CY位进行三者数据相加,相加结果送入累加器A中,影响PSW的标志位情况与ADD指令相同。 (8) ADDCA,#data指令 指令机器码: 0 0 1 10 1 0 0 #data 指令实现的操作: 将ROM中的立即数与累加器A的内容以及在最低位上与PSW的CY位进行三者数据相加,相加结果送入累加器A中,影响PSW的标志位情况与ADD指令相同。 2. 算术减运算指令 (1) SUBBA,Rn 指令 指令机器码: 1 0 0 11 r r r 指令实现的操作: 实现8位无符号数的减法运算,将累加器A中的内容减去工作寄存器Rn(R0~R7)之一的内容,同时在最低位(第0位)上减去PSW的CY(进位位)的数值,相减结果送入累加器A中。 该指令影响程序状态字PSW的CY、AC、OV、P标志位,当第7位相减结果产生借位时CY=1; 当第3位相减结果产生借位时AC=1; 当使用该指令实现有符号数据相减运算时,OV=1表示运算有溢出,它将破坏正确的符号位运算结果; 当送入累加器A中的运算结果有奇数个1时,P=1。 51单片机CPU的运算指令是对一个字节而言的,在实现多字节减法运算时,低字节相减会向高字节产生借位(CY=1),当在高字节进行相减运算时使用该指令正好实现带借位的相减运算。由于该CPU没有不带借位相减运算的指令,因此,为保证运算结果的正确性,在做单字节或多字节的减法运算之前,需要将CY清0(CLR CY)。 (2) SUBBA,direct指令 指令机器码: 1 0 0 10 1 0 1 direct 指令实现的操作: 将累加器A中的内容减去直接地址单元direct中的内容,同时在第0位上减去PSW的CY的数值,相减结果送入累加器A中。SUBB指令影响程序状态字PSW的标志位情况相同。 (3) SUBBA,@Ri指令 指令机器码: 1 0 0 10 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为内部存储器RAM地址(间接寻址单元),将累加器A中的内容减去Ri指示的内部RAM地址中的内容,同时在第0位上减去PSW的CY的数值,相减结果送入累加器A中。SUBB指令影响程序状态字PSW的标志位情况相同。 (4) SUBBA,#data指令 指令机器码: 1 0 0 10 1 0 0 #data 指令实现的操作: 将累加器A中的内容减去ROM中的立即数,同时在第0位上减去PSW的CY的数值,相减结果送入累加器A中。SUBB指令影响程序状态字PSW的标志位情况相同。 3. 算术加1操作指令 (1) INCA指令 指令机器码: 0 0 0 00 1 0 0 指令实现的操作: 累加器A中的内容加1,该指令影响PSW中的P标志位,当加1后累加器A中有奇数个1时,P=1。 (2) INCRn指令 指令机器码: 0 0 0 01 r r r 指令实现的操作: 工作寄存器Rn(R0~R7)之一的内容加1,该指令不影响PSW标志位。 (3) INCdirect指令 指令机器码: 0 0 0 00 1 0 1 direct 指令实现的操作: RAM直接地址单元direct中的内容加1,该指令不影响PSW标志位。 (4) INC@Ri指令 指令机器码: 0 0 0 00 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为内部RAM地址(间接寻址单元),将Ri指示的内部RAM地址中的内容加1,该指令不影响PSW标志位。 (5) INCDPTR指令 指令机器码: 1 0 1 00 0 1 1 指令实现的操作: DPTR寄存器中的内容加1,该指令不影响PSW标志位。 4. 算术减1操作指令 (1) DECA指令 指令机器码: 0 0 0 10 1 0 0 指令实现的操作: 累加器A中的内容减1,该指令影响PSW中的P标志位,当减1后累加器A中有奇数个1时,P=1。 (2) DECRn指令 指令机器码: 0 0 0 11 r r r 指令实现的操作: 工作寄存器Rn(R0~R7)之一的内容减1,该指令不影响PSW标志位。 (3) DECdirect指令 指令机器码: 0 0 0 10 1 0 1 direct 指令实现的操作: RAM直接地址单元direct中的内容减1,该指令不影响PSW标志位。 (4) DEC@Ri指令 指令机器码: 0 0 0 10 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为内部RAM地址(间接寻址单元),将Ri指示的内部RAM地址中的内容减1,该指令不影响PSW标志位。 5. 算术乘、除运算指令 (1) MULAB指令 指令机器码: 1 0 1 00 1 0 0 指令实现的操作: 两个8位无符号整数数据相乘,累加器A中的内容乘以寄存器B中的内容,所得16位乘积,乘积的高8位送入寄存器B中,乘积的低8位送入累加器A中,该乘法指令影响程序状态字PSW的OV、P标志位,当乘积大于0FFH时,OV=1; P标志位反映累加器A中数据的奇偶性。 (2) DIVAB指令 指令机器码: 1 0 0 00 1 0 0 指令实现的操作: 两个8位无符号整数数据相除,累加器A中的内容除以寄存器B中的内容,所得商送入累加器A中,余数送入寄存器B中,该除法指令影响程序状态字PSW的OV、P标志位,当寄存器B中的内容(除数)为0时,OV=1,其操作非法,结果不正确; P标志位反映累加器A中数据的奇偶性。 6. 十进制调整指令 DAA指令 指令机器码: 1 1 0 10 1 0 0 指令实现的操作: 十进制调整,将累加器A中的内容调整为BCD码,其调整的原则如下。 若A0~A3>9或PSW的标志位AC=1,则累加器A低4位(A0~A3)加6再送回累加器A低4位中。 若A4~A7 >9或PSW的标志位CY=1,则累加器A高4位(A4~A7)加6再送回累加器A高4位中。 即CPU根据累加器A中的原始数据和PSW的CY、AC标志位,自动实现对累加器A中的内容加06H或60H或66H的操作。 该指令是对累加器A中的BCD码相加结果进行调整,当两个BCD码按二进制数据相加后,需要该指令参与调整才能得到正确的BCD码结果,在该指令被执行后,当CY=1时,说明BCD码的结果(值)≥100。 3.4逻辑运算类指令 51单片机的逻辑运算指令是实现8位二进制数据按位进行逻辑运算的,其运算包括逻辑与、或、异或、非,以及左移、右移、循环移位等操作。 3.4.1逻辑运算指令 51单片机CPU有24条逻辑运算指令,逻辑运算指令的助记符、完成的功能、影响程序状态字PSW的标志位、占用存储器字节数、CPU执行指令所用时间(机器周期)等如表36所示。 表3651单片机CPU逻辑运算指令表 机器码 助记符 操作码 操作数 功能 影响PSW标志位 CY AC OV P 字节数 机器周期 58~5F ANL A,Rn A←A∧Rn(n=0~7) × × × √ 1 1 55 ANL A,direct A←A∧(direct) × × × √ 2 1 56、57 ANL A,@Ri A←A∧(Ri)(i=0,1) × × × √ 1 1 54 ANL A,#data A←A∧data × × × √ 2 1 52 ANL direct,A (direct)←(direct)∧A × × × × 2 1 53 ANL direct,#data (direct)←(direct)∧data × × × × 3 2 48~4F ORL A,Rn A←A∨Rn(n=0~7) × × × √ 1 1 45 ORL A,direct A←A∨(direct) × × × √ 2 1 46、47 ORL A,@Ri A←A∨(Ri)(i=0,1) × × × √ 1 1 44 ORL A,#data A←A∨data × × × √ 2 1 42 ORL direct,A (direct)←(direct)∨A × × × × 2 1 43 ORL direct,#data (direct)←(direct)∨data × × × × 3 2 68~6F XRL A,Rn A←ARn(n=0~7) × × × √ 1 1 65 XRL A,direct A←A(direct) × × × √ 2 1 66、67 XRL A,@Ri A←A(Ri)(i=0,1) × × × √ 1 1 续表 机器码 助记符 操作码 操作数 功能 影响PSW标志位 CY AC OV P 字节数 机器周期 64 XRL A,#data A←Adata × × × √ 2 1 62 XRL direct,A (direct)←(direct)A × × × × 1 1 63 XRL direct,#data (direct)←(direct)data × × × × 3 2 F4 CPL A A← × × × × 1 1 E4 CLR A A←0 × × × √ 1 1 23 RL A × × × × 1 1 33 RLC A √ × × √ 1 1 03 RR A × × × × 1 1 13 RRC A √ × × √ 1 1 3.4.2逻辑运算指令详解 51单片机CPU的逻辑运算指令实现了二进制数据按位进行的逻辑与、逻辑或、逻辑异或、逻辑非、循环移位操作等,其部分指令只影响程序状态字PSW的P标志位。 1. 逻辑与运算指令 (1) ANLA,Rn指令 指令机器码: 0 1 0 11 r r r 指令实现的操作: 将累加器A中的内容同工作寄存器Rn(R0~R7)之一的内容按位进行“逻辑与”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (2) ANLA,direct指令 指令机器码: 0 1 0 10 1 0 1 direct 指令实现的操作: 将累加器A中的内容同RAM直接地址单元direct中的内容按位进行“逻辑与”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (3) ANLA,@Ri指令 指令机器码: 0 1 0 10 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为内部RAM地址(间接寻址单元),将累加器A中的内容同Ri指示的内部RAM地址中的内容按位进行“逻辑与”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (4) ANLA,#data指令 指令机器码: 0 1 0 10 1 0 0 #data 指令实现的操作: 将累加器A中的内容同ROM中的立即数按位进行“逻辑与”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (5) ANLdirect,A指令 指令机器码: 0 1 0 10 0 1 0 direct 指令实现的操作: 将RAM直接地址单元direct中的内容同累加器A中的内容按位进行“逻辑与”操作,结果送入直接地址单元direct中。 (6) ANLdirect,#data指令 指令机器码: 0 1 0 10 0 1 1 direct #data 指令实现的操作: 将RAM直接地址单元direct中的内容同ROM中的立即数按位进行“逻辑与”操作,结果送入直接地址单元direct中。 2. 逻辑或运算指令 (1) ORLA,Rn指令 指令机器码: 0 1 0 01 r r r 指令实现的操作: 将累加器A中的内容同工作寄存器Rn(R0~R7)之一的内容按位进行“逻辑或”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (2) ORLA,direct指令 指令机器码: 0 1 0 00 1 0 1 direct 指令实现的操作: 将累加器A中的内容同RAM直接地址单元direct中的内容按位进行“逻辑或”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (3) ORLA,@Ri指令 指令机器码: 0 1 0 00 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为内部RAM地址(间接寻址单元),将累加器A中的内容同Ri指示的内部RAM地址中的内容按位进行“逻辑或”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (4) ORLA,#data指令 指令机器码: 0 1 0 00 1 0 0 #data 指令实现的操作: 将累加器A中的内容同ROM中的立即数按位进行“逻辑或”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (5) ORLdirect,A指令 指令机器码: 0 1 0 00 0 1 0 direct 指令实现的操作: 将RAM直接地址单元direct中的内容同累加器A中的内容按位进行“逻辑或”操作,结果送入直接地址单元direct中。 (6) ORLdirect,#data指令 指令机器码: 0 1 0 00 0 1 1 direct #data 指令实现的操作: 将RAM直接地址单元direct中的内容同ROM中的立即数按位进行“逻辑或”操作,结果送入直接地址单元direct中。 3. 逻辑异或运算指令 (1) XRLA,Rn指令 指令机器码: 0 1 1 01 r r r 指令实现的操作: 将累加器A中的内容同工作寄存器Rn(R0~R7)之一的内容按位进行“逻辑异或”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (2) XRLA,direct指令 指令机器码: 0 1 1 00 1 0 1 direct 指令实现的操作: 将累加器A中的内容同RAM直接地址单元direct中的内容按位进行“逻辑异或”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (3) XRLA,@Ri指令 指令机器码: 0 1 1 00 1 1 i 指令实现的操作: 工作寄存器Ri(R0~R1)之一中的数据作为内部RAM地址(间接寻址单元),将累加器A中的内容同Ri指示的内部RAM地址中的内容按位进行“逻辑异或”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (4) XRLA,#data指令 指令机器码: 0 1 1 00 1 0 0 #data 指令实现的操作: 将累加器A中的内容同ROM中的立即数按位进行“逻辑异或”操作,结果送入累加器A中,该指令影响PSW的P标志位。 (5) XRLdirect,A指令 指令机器码: 0 1 1 00 0 1 0 direct 指令实现的操作: 将RAM直接地址单元direct中的内容同累加器A中的内容按位进行“逻辑异或”操作,结果送入直接地址单元direct中。 (6) XRLdirect,#data指令 指令机器码: 0 1 1 00 0 1 1 direct #data 指令实现的操作: 将RAM直接地址单元direct中的内容同ROM中的立即数按位进行“逻辑异或”操作,结果送入直接地址单元direct中。 4. 逻辑非运算指令 (1) CPLA指令 指令机器码: 1 1 1 10 1 0 0 指令实现的操作: 将累加器A中的内容按位进行“求反”操作,结果送入累加器A中。 (2) CLRA指令 指令机器码: 1 1 1 00 1 0 0 指令实现的操作: 将累加器A中的内容按位进行“清0”操作,结果送入累加器A中。 5. 循环移位操作指令 (1) RLA指令 指令机器码: 0 0 1 00 0 1 1 指令实现的操作: 将累加器A中的内容按位循环左移一位,其左移过程为: A0←A7←A6←A5←A4←A3←A2←A1←A0。 (2) RLCA指令 指令机器码: 0 0 1 10 0 1 1 指令实现的操作: 将累加器A中的内容连同进位位按位循环左移一位,该指令影响PSW的CY、P标志位,其左移过程为: CY←A7←A6←A5←A4←A3←A2←A1←A0←CY。 (3) RRA指令 指令机器码: 0 0 0 00 0 1 1 指令实现的操作: 将累加器A中的内容按位循环右移一位,其右移过程为: A7→A6→A5→A4→A3→A2→A1→A0→A7。 (4) RRCA指令 指令机器码: 0 0 0 10 0 1 1 指令实现的操作: 将累加器A中的内容连同进位位按位循环右一位,该指令影响PSW的CY、P标志位,其右移过程为: CY→A7→A6→A5→A4→A3→A2→A1→A0→CY。 3.5控制转移类指令 控制转移类指令是用于控制改变程序执行流向的指令,该类指令包括无条件转移指令、条件转移指令、子程序调用指令、子程序返回指令、中断返回指令等。 3.5.1控制转移指令 51单片机CPU共有17条控制转移指令,这些指令的助记符、完成的功能、影响程序状态字PSW的标志位、占用存储器字节数、CPU执行指令所用时间(机器周期)等如表37所示。 表3751单片机CPU控制转移指令表 机器码 助记符 操作码 操作数 功能 影响PSW标志位 CY AC OV P 字节数 机器周期 *1 AJMP addr11 PC←PC+2,PC10~0←addr11 × × × × 2 2 02 LJMP addr16 PC←addr16 × × × × 3 2 80 SJMP rel PC←PC+2,PC←PC+rel × × × × 2 2 73 JMP @A+DPTR PC←(A+DPTR) × × × × 1 2 60 JZ rel PC←PC+2, if A=0; then PC←PC+rel × × × × 2 2 70 JNZ rel PC←PC+2, if A≠0; then PC←PC+rel × × × × 2 2 B5 CJNE A,direct,rel PC←PC+3, if A≠(direct); then PC←PC+rel if A<(direct); then CY←1 √ × × × 3 2B4 CJNE A,#data,rel PC←PC+3, if A≠data; then PC←PC+rel if A< data; then CY←1 √ × × × 3 2 B8~BF CJNE Rn,#data,rel PC←PC+3, if Rn≠data; then PC←PC+rel if Rn< data; then CY←1(n=0~7) √ × × × 3 2 B6、B7 CJNE @Ri,#data,rel PC←PC+3, if(Ri)≠data; then PC←PC+rel if(Ri)< data; then CY←1(i=0、1) √ × × × 3 2 D8~DF DJNZ Rn,rel Rn←Rn - 1,PC←PC+2, if Rn≠0; then PC←PC+rel(n=0~7) √ × × × 2 2 续表 机器码 助记符 操作码 操作数 功能 影响PSW标志位 CY AC OV P 字节数 机器周期 D5 DJNZ direct,rel (direct)←(direct)-1,PC←PC+2, if(direct)≠0; then PC←PC+rel √ × × × 3 2 *1 ACALL addr11 PC←PC+2,SP←SP+1, (SP)←PCL,SP←SP+1, (SP)←PCH,PC10~0←addr11 × × × × 2 2 12 LCALL addr16 PC←PC+3,SP←SP+1, (SP)←PCL,SP←SP+1, (SP)←PCH,PC←addr16 × × × × 3 2 22 RET PCH←(SP),SP←SP-1, PCL←(SP),SP←SP-1 × × × × 1 2 32 RETI PCH←(SP),SP←SP-1, PCL←(SP),SP←SP-1,CLR I_flag × × × × 1 2 00 NOP no × × × × 1 1 3.5.2控制转移指令详解 控制转移指令用于改变程序执行流向,包含无条件转移、条件转移、子程序调用、返回等指令。 1. 无条件转移指令 (1) AJMPaddr11指令 指令机器码: a10 a9 a8 0 0 0 0 1 a7~a0 指令实现的操作: 无条件绝对转移,首先程序计数器PC的内容加2,然后将指令机器码中a10~a0送入PC10~PC0中,PC15~ PC11内容不变。 AJMP指令在指令机器码中指出低11位程序存储器ROM的地址,该指令可控制程序在2KB的范围内无条件转移执行,转移范围如图33(a)所示。 (2) LJMPaddr16指令 指令机器码: 0 0 0 00 0 1 0 a15~a8 a7~a0 指令实现的操作: 无条件绝对长转移,将指令机器码中a15~a0送入PC15~PC0中。 LJMP指令在指令机器码中指出16位程序存储器ROM的地址,该指令可控制程序在64KB的范围内无条件转移执行,转移范围如图33(b)所示。 图33AJMP、LJMP转移范围 (3) SJMPrel指令 指令机器码: 1 0 0 00 0 0 0 rel(相对地址) 指令实现的操作: 无条件相对转移,首先程序计数器PC的内容加2,此时PC 值是相对转移地址的基准值,然后将PC中的数值与转移偏移量rel数值(有符号数)按有符号数据相加,相加结果送入PC中,rel表示为8位有符号数据,因此,SJMP指令的控制程序转移范围在-128~+127B之间,如图34(a)所示。 图34SJMP、JMP转移范围 (4) JMP@A+DPTR指令 指令机器码: 0 1 1 10 0 1 1 指令实现的操作: 无条件间接转移,也被称为散转指令,该指令的转移地址由16位数据指针寄存器DPTR的内容与8位累加器A的内容进行无符号数相加形成,将相加结果送入程序计数器PC中,其转移范围是以DPTR的内容为首地址的256B之内,并以DPTR的内容为基准向程序存储器ROM地址增长方向转移,如图34(b)所示。 2. 比较(条件)转移指令 (1) JZrel指令 指令机器码: 0 1 1 00 0 0 0 rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加2,然后对累加器A的内容进行检测,当A的各位全部为0时,满足转移条件,将PC中的数值与转移偏移量rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,该指令控制程序转移范围为-128~+127B; 当A不为0时,CPU执行该指令的下一条指令,CPU执行该指令的流程如图35(a)所示。 图35JZ、JNZ指令执行流程 (2) JNZrel指令 指令机器码: 0 1 1 10 0 0 0 rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加2,然后对累加器A的内容进行检测,当A不为0时,满足转移条件,将PC中的数值与转移偏移量rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,该指令控制程序转移范围为-128~+127B; 当A为全0时,CPU执行该指令的下一条指令,CPU执行该指令的流程如图35(b)所示。 (3) CJNEA,direct,rel指令 指令机器码: 1 0 1 10 1 0 1 direct rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加3,然后将累加器A的内容与RAM直接地址单元direct中的内容进行比较,当两者不相等时,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,该指令控制程序转移范围为-128~+127B,另外,该指令影响程序状态字PSW的CY标志位,当A的内容大于direct中的内容时,CY=0; 当A的内容小于direct中的内容时,CY=1; 当A与direct中的内容相等时,CY=0,CPU执行该指令的下一条指令,CPU执行该指令以及影响CY标志位的流程如图36所示。 图36CJNE指令执行流程 (4) CJNEA,#data,rel指令 指令机器码: 1 0 1 10 1 0 0 #data rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加3,然后将累加器A的内容与ROM中的立即数进行比较,当两者不相等时,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,控制转移范围为-128~+127B; 当参与比较的两个数据相等时,执行下一条指令,CJNE指令执行流程以及影响程序状态字PSW的CY标志位都相同。 (5) CJNERn,#data,rel指令 指令机器码: 1 0 1 11 r r r #data rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加3,然后将工作寄存器Rn(R0~R7)之一的内容与ROM中的立即数进行比较,当两者不相等时,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,控制转移范围为-128~+127B; 当参与比较的两个数据相等时,执行下一条指令,CJNE指令执行流程以及影响程序状态字PSW的CY标志位都相同。 (6) CJNE@Ri,#data,rel指令 指令机器码: 1 0 1 10 1 1 i #data rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加3,然后将工作寄存器Ri(R0~R1)之一中的数据作为内部RAM地址(间接寻址单元),并将Ri指示的内部RAM地址中的内容与ROM中的立即数进行比较,当两者不相等时,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,控制转移范围为-128~+127B; 当参与比较的两个数据相等时,执行下一条指令,CJNE指令执行流程以及影响程序状态字PSW的CY标志位都相同。 3. 循环转移指令 (1) DJNZRn,rel指令 指令机器码: 1 1 0 11 r r r rel(相对地址) 图37DJNZ指令执行流程 指令实现的操作: 首先程序计数器PC的内容加2,然后将工作寄存器Rn(R0~R7)之一的内容减1,并对寄存器Rn的内容进行检测,当Rn的内容不为0时,满足转移条件,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,转移范围为-128~+127B; 当Rn的内容为0时,CPU执行该指令的下一条指令,CPU执行该指令的流程如图37所示。 (2) DJNZdirect,rel指令 指令机器码: 1 1 0 10 1 0 1 direct rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加3,然后将RAM直接地址单元direct中的内容减1,并对direct中的内容进行检测,当direct中的内容不为0时,满足转移条件,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,转移范围为-128~+127B; 当direct中的内容为0时,CPU执行该指令的下一条指令,CPU执行DJNZ指令的流程是一样的,如图37所示。 4. 子程序调用指令 (1) ACALLaddr11指令 指令机器码: a10 a9 a8 1 0 0 0 1 a7~a0 指令实现的操作: 首先程序计数器PC的内容加2,并将堆栈指针寄存器SP的内容加1,PC7~PC0低8位送入堆栈,SP再加1,PC15~PC8高8位送入堆栈,然后将指令机器码中a10~a0送入PC10~PC0中,PC15~ PC11内容不变。 ACALL指令在指令机器码中指出低11位程序存储器ROM的地址,该指令可控制程序在2KB范围内实现子程序的调用。 (2) LCALLaddr16指令 指令机器码: 0 0 0 10 0 1 0 a15~a8 a7~a0 指令实现的操作: 首先程序计数器PC的内容加3,并将堆栈指针寄存器SP的内容加1,PC7~PC0低8位送入堆栈,SP再加1,PC15~PC8高8位送入堆栈,然后将指令机器码中a15~a0送入PC15~PC0中,该指令可控制程序在64KB范围内实现子程序的调用,另外,CALL助记符与LCALL等同。 5. 返回指令 (1) RET指令 指令机器码: 0 0 1 00 0 1 0 指令实现的操作: 子程序返回,将堆栈数据出栈送入PC15~PC8高8位,堆栈指针寄存器SP的内容减1,再将堆栈数据出栈送入PC7~PC0低8位,SP再减1。 (2) RETI指令 指令机器码: 0 0 1 10 0 1 0 指令实现的操作: 中断程序返回,将堆栈数据出栈送入PC15~PC8高8位,堆栈指针寄存器SP的内容减1,再将堆栈数据出栈送入PC7~PC0低8位,SP再减1。另外,该指令还清除中断逻辑,例如,清除CPU内部中断标志。 6. 空操作指令 NOP指令 指令机器码: 0 0 0 00 0 0 0 指令实现的操作: 空操作,程序计数器PC的内容加1,该指令用于产生一个机器周期的延迟。 3.6位操作、位控制转移类指令 位操作、位控制转移类指令是专门针对内部RAM字节地址为20H~2FH(位地址00H~7FH)的位存储单元以及特殊功能寄存器SFR中具有位访问能力的寄存器进行位操作而设计的,其操作的数据宽度是以位(1bit)为单位的,指令包括逻辑位运算、位数据传输、根据位状态实现程序的转移执行等操作指令。 3.6.1位操作、位控制转移指令 51单片机CPU共有17条位操作、位控制转移指令,这些指令的助记符、完成的功能、影响程序状态字PSW的标志位、占用存储器字节数、CPU执行指令所用时间(机器周期)等如表38所示。 表3851单片机CPU位操作、位控制转移指令表 机器码 助记符 操作码 操作数 功能 影响PSW标志位 CY AC OV P 字节数 机器周期 C3 CLR C CY←0 0 × × × 1 1 C2 CLR bit bit←0 × × × × 2 1 D3 SETB C CY←1 1 × × × 1 1 D2 SETB bit bit←1 × × × × 2 1 B3 CPL C CY←CY √ × × × 1 1 B2 CPL bit bit←bit × × × × 2 1 82 ANL C,bit CY←CY∧bit √ × × × 2 2 B0 ANL C,bit CY←CY∧bit √ × × × 2 2 72 ORL C,bit CY←CY∨bit √ × × × 2 2 A0 ORL C,bit CY←CY∨bit √ × × × 2 2 A2 MOV C,bit CY←bit √ × × × 2 1 92 MOV bit,C bit←CY × × × × 2 2 40 JC rel PC←PC+2, if CY=1; then PC←PC+rel × × × × 2 2 50 JNC rel PC←PC+2, if CY≠1; then PC←PC+rel × × × × 2 2 20 JB bit,rel PC←PC+3, if bit=1; then PC←PC+rel × × × × 3 2 30 JNB bit,rel PC←PC+3, if bit≠1; then PC←PC+rel × × × × 3 2 10 JBC bit,rel PC←PC+3, if bit=1; then PC←PC+rel,bit←0 × × × × 3 2 3.6.2位操作、位控制转移指令详解 位操作、位控制转移指令有对某一位进行清0或置1、位逻辑运算、位数据传输、根据位状态实现程序的转移执行等操作。 1. 位清0、置1指令 (1) CLRC指令 指令机器码: 1 1 0 00 0 1 1 指令实现的操作: 将程序状态字PSW中CY进位位清0。 (2) CLRbit指令 指令机器码: 1 1 0 00 0 1 0 bit(位地址) 指令实现的操作: 将内部RAM位地址为00H~7FH之间的位地址为bit的位存储单元清0。 (3) SETBC指令 指令机器码: 1 1 0 10 0 1 1 指令实现的操作: 将程序状态字PSW中CY进位位置1。 (4) SETBbit指令 指令机器码: 1 1 0 10 0 1 0 bit(位地址) 指令实现的操作: 将内部RAM位地址为00H~7FH之间的位地址为bit的位存储单元置1。 2. 位逻辑运算指令 (1) CPLC指令 指令机器码: 1 0 1 10 0 1 1 指令实现的操作: 将程序状态字PSW中CY进位位进行求反后送回CY。 (2) CPLbit指令 指令机器码: 1 0 1 10 0 1 0 bit(位地址) 指令实现的操作: 将内部RAM位地址为bit位存储单元的内容进行求反后送回bit单元中。 (3) ANLC,bit指令 指令机器码: 1 0 0 00 0 1 0 bit(位地址) 指令实现的操作: 将内部RAM位地址为bit位存储单元的内容与程序状态字PSW中CY进位位进行“逻辑与”操作,将操作结果送入CY中。 (4) ANLC,bit指令 指令机器码: 1 0 1 10 0 0 0 bit(位地址) 指令实现的操作: 将内部RAM位地址为bit位存储单元的内容求反后与程序状态字PSW中CY进位位进行“逻辑与”操作,将操作结果送入CY中。 (5) ORLC,bit指令 指令机器码: 0 1 1 10 0 1 0 bit(位地址) 指令实现的操作: 将内部RAM位地址为bit位存储单元的内容与程序状态字PSW中CY进位位进行“逻辑或”操作,将操作结果送入CY中。 (6) ORLC,bit指令 指令机器码: 1 0 1 00 0 0 0 bit(位地址) 指令实现的操作: 将内部RAM位地址为bit位存储单元的内容求反后与程序状态字PSW中CY进位位进行“逻辑或”操作,将操作结果送入CY中。 3. 位传输指令 (1) MOVC,bit指令 指令机器码: 1 0 1 00 0 1 0 bit(位地址) 指令实现的操作: 将内部RAM位地址为bit位存储单元的内容送入程序状态字PSW的CY进位位中。 (2) MOVbit,C指令 指令机器码: 1 0 0 10 0 1 0 bit(位地址) 指令实现的操作: 将程序状态字PSW中CY进位位的内容送入内部RAM位地址为bit的位存储单元中。 4. 位判断转移指令 (1) JCrel指令 指令机器码: 0 1 0 00 0 0 0 rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加2,然后对程序状态字PSW中CY进位位的内容进行检测,当CY为1时,满足转移条件,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,该指令控制程序转移范围为-128~+127B; 当CY为0时,CPU执行该指令的下一条指令。 (2) JNCrel指令 指令机器码: 0 1 0 10 0 0 0 rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加2,然后对程序状态字PSW中CY进位位的内容进行检测,当CY不为1时,满足转移条件,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,该指令控制程序转移范围为-128~+127B; 当CY为1时,CPU执行该指令的下一条指令。 (3) JBbit,rel指令 指令机器码: 0 0 1 00 0 0 0 bit(位地址) rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加3,然后对内部RAM位地址为bit位存储单元的内容进行检测,当该单元内容为1时,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,该指令控制程序转移范围为-128~+127B; 当bit单元内容为0时,CPU执行该指令的下一条指令。 (4) JNBbit,rel指令 指令机器码: 0 0 1 10 0 0 0 bit(位地址) rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加3,然后对内部RAM位地址为bit位存储单元的内容进行检测,当该单元内容不为1时,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,该指令控制程序转移范围为-128~+127B; 当bit单元内容为1时,CPU执行该指令的下一条指令。 (5) JBCbit,rel指令 指令机器码: 0 0 0 10 0 0 0 bit(位地址) rel(相对地址) 指令实现的操作: 首先程序计数器PC的内容加3,然后对内部RAM位地址为bit位存储单元的内容进行检测,当该单元内容为1时,将PC中的数值与rel数值按有符号数据相加,相加结果送入PC中,实现程序转移执行,同时将bit位存储单元清0; 当bit单元内容为0时,CPU执行该指令的下一条指令。 3.7伪指令 伪指令是用于通知汇编器如何进行汇编源程序的指令,又被称为命令语句,在由指令助记符和伪指令组成的源程序代码中,伪指令语句除定义的具体数据要生成目标代码外,其他均没有对应的目标代码(或可执行的指令机器码),伪指令的功能是由汇编器在汇编源程序时被实现的,并非在CPU运行指令机器码组成的机器码程序实现。另外,当硬件发生改变时,通过伪指令可使修改程序变得容易。 3.7.1常用伪指令 51汇编语言常用的伪指令及其功能如表39所示。 表3951汇编语言常用伪指令表 助记符 功能 ORG 汇编起始地址伪指令,定义指令机器码起始地址 END 汇编结束伪指令,通知汇编器不再汇编 EQU 等值定义伪指令,定义数据或存储器地址 DATA 地址数据赋值伪指令,定义(8位或16位)存储器地址 DB、DW 程序存储器字节(字)数据类型定义伪指令,定义ROM中的字节(字)常量 DS 程序存储器地址保留量定义伪指令,在ROM中定义一段存储空间 BIT 位地址符号定义伪指令,定义位存储器单元地址 3.7.2伪指令详解 伪指令用于指导汇编器对指令源程序进行汇编的,主要指明指令机器码放在程序存储器的什么位置、存储单元如何分配、定义存储单元地址、定义常量数据等。 1. ORG伪指令 使用格式: ORG表达式 ORG伪指令的功能是规定该伪指令后面的指令源程序汇编后生成机器代码存放在ROM中的起始地址,表达式可以是一个具体的数值,例如,16位地址,也可以是包含变量名的表达式,而变量在汇编器汇编到该伪指令时已经是被赋予了实际整数数值的。 2. END伪指令 使用格式: END END伪指令的功能是通知汇编器停止汇编,在END伪指令后面的指令源程序不会被汇编成指令机器代码。 3. EQU伪指令 使用格式: 符号名称EQU表达式 EQU伪指令也被称为等值伪指令,它用来说明“符号名称”等于一个表达式得出的值,表达式的值可以是16位或8位的二进制数值,也可以是字符串,当表达式的值是字符串时,只取后两个字符,“符号名称”是以字母开头的字母和数字的组合,在源程序中“符号名称”不可出现重名,使用EQU赋值的“符号名称”可作为数据(立即数)、数据地址、代码地址、位地址等使用。 4. DATA伪指令 使用格式: 符号名称DATA表达式 DATA伪指令也被称为数据地址赋值伪指令,该伪指令用来定义RAM中一个字节类型的存储单元,即赋予一个字节类型的存储单元一个“符号名称”,以便在指令源程序中通过“符号名称”来访问(读、写)这个存储单元,“符号名称”的组成规则与EQU伪指令中的“符号名称”组成规则相同。 5. DB、DW伪指令 使用格式: [标号: ]DB表达式1,表达式2,…,表达式n 使用格式: [标号: ]DW表达式1,表达式2,…,表达式n DB伪指令用于定义一个连续的字节存储区(在程序存储ROM区域),并给该存储区的字节存储单元赋予数值,表达式的值为一个字节类型的数据或字符,如果是字符需要括在单引号“'”中,每个数据或字符用逗号分开,该伪指令在使用时需要容纳在源程序代码的一行内,即不能换行,在该伪指令使用格式中“标号: ”是可选项。 DW伪指令与DB伪指令功能相同,DW伪指令是为字存储单元(在ROM区域)赋值的,规则为高8位存放在前(在ROM区域存储单元地址为N),低8位存放在后(在ROM区域存储单元地址为N+1)。 6. DS伪指令 使用格式: [标号: ]DS表达式1,[表达式2] DS伪指令用于定义一个长度为表达式1计算值的连续存储空间,表达式1得出的值是存储空间包含的字节数,即在ROM区域保留长度为表达式1数值个字节数的存储单元,表达式2是可选项,表达式2用于指定填满存储空间的数值。 7. BIT伪指令 使用格式: 符号名称BIT表达式 BIT伪指令也被称为位数据地址赋值伪指令,该伪指令用来定义一个位存储单元,即赋予位地址一个“符号名称”,以便在指令源程序中通过“符号名称”来访问(读、写)这个位存储单元,“符号名称”的组成规则与EQU伪指令中的“符号名称”组成规则相同。 3.8指令程序 指令程序分为指令源代码程序和指令机器代码程序,指令源代码程序由指令助记符组成,包括指令机器码助记符和伪指令,它是用文本格式表述的; 指令机器代码程序是由指令机器码组成的,它是51单片机CPU可执行的程序,用二进制数据格式表述。 3.8.1指令源代码程序格式 计算机程序的设计是在指令源代码的基础上实现的。源代码由机器码助记符或伪指令组成,每一条机器码指令(助记符)或伪指令被称为一条程序语句,或称为汇编语句,源代码程序是由多条程序语句组成的,它也被称为汇编语言程序,51单片机汇编语言程序中程序语句的编写格式为 [标号: ]指令或伪指令[; 注释] 指令即指机器码指令,包括操作码和操作数,按照每条指令的格式出现在程序语句中; 伪指令同样也是按照伪指令的格式出现在程序语句中的,“标号: ”是程序语句中的可选项,用于指明程序语句中指令或伪指令在程序存储ROM区域存放的存储单元地址,当指令机器码或伪指令中定义的数据占用多个存储单元时,标号指示的是首地址,“; 注释”也为可选项,为该条程序语句提供注释。 3.8.2指令源代码程序设计 指令按照程序语句格式编写的多条语句的集合被称为源程序,程序的设计体现了安排CPU工作的过程,CPU工作的步骤反映在程序设计上,遗憾的是,使用51单片机汇编语言设计程序只需遵守指令编写格式即可,并没有设计规则,其源程序只是汇编语句的堆积,每条汇编语句都指挥CPU完成一个动作,多条汇编语句的组合实现一个功能,而多条汇编语句组合的逻辑关系则需要人为确定,为了方便源程序的设计,建议使用逻辑框图来描述程序实现的功能,它也反映了CPU运行的流程,逻辑框图使用的图符如表310所示。 表310源程序设计经常使用的框图图符表 图符 描述 程序开始执行和结束执行 程序完成的单项任务 程序执行流向指示 程序中出现的判断分支 依据51单片机CPU指令系统提供的功能,其所能实现的程序设计有顺序程序设计、分支程序设计、循环程序设计、子程序设计等,其程序功能设计框图如图38所示。 图38程序功能设计框图 3.8.3源代码程序的编译 由汇编指令(助记符)和伪指令组成的源程序代码是不能在51单片机上运行的,需要将它编译成指令机器代码(可执行代码),编译的过程如图39所示,将指令机器代码写入51单片机的程序存储器ROM中才可以被执行。 图39源程序代码编译为指令机器代码 目前,51单片机的生产厂商提供了多种编译工具,尤其是应用于PC的编译工具被广泛使用,例如C51(Compiler51)汇编器等编译工具。在PC上编写51单片机的应用程序需要如下步骤。 (1) 编码: 编写文本格式的源程序代码,并以*.asm为文件名保存在磁盘中; (2) 编译: 使用编译工具将源程序代码编译成目标代码(由机器代码和重定位信息组成)或指令机器代码,有些汇编器输出的是目标代码文件,文件名为*.obj,需要使用链接器将目标代码文件转换成指令机器代码,有些编译工具可直接产生指令机器代码,指令机器代码有两种文件格式,*.bin(二进制可执行文件)和*.hex(Intel公司制定按地址排列的十六进制数据信息文件)。 (3) 执行: 使用专用51单片机ROM数据文件写入设备将*.bin或*.hex文件写入ROM中,或应用ISP(In System Programming)技术将可执行文件写入51单片机的ROM中。 3.8.4源代码程序设计示例 通过设计汇编语言源代码程序可以熟悉和掌握51单片机指令的使用,下面是几个常用的汇编语言源代码程序的设计和程序执行流程框图。 1. 数据传送源程序 图310数据移动程序执行流程 将内部RAM地址为20H~2FH单元中的数据按顺序传送到70H~7FH单元中,CPU执行流程如图310所示,源程序代码如下。 ORG0000H LJMPSTART;程序开始 ORG0030H START:MOVR0,#20H;初始化 MOVR1,#70H MOVR2,#10H LOOP: MOVA,@R0;移动数据 MOV@R1,A INCR0;地址+1 INCR1 DJNZR2,LOOP;计数器-1 SJMP$;结束,等待 END 说明: R0存放源数据地址,R1存放目的数据地址,R2为一个计数器。 2. 软件延时源程序 软件延时是经常使用的一种时间定时方法,当51单片机的时钟频率(振荡频率fosc)确定后,每条指令的执行周期是确定的,根据指令的执行周期(包含的机器周期)可以计算出延时的时间,下面是一个软件延时子程序代码。 ORG0100H MOVR7,#00H;将R7清0,执行该指令需要1个机器周期 MOVR6,#00H ;将R6清0,执行该指令需要1个机器周期 DELAY: DJNZR7,DELAY ;R7-1非0转移,执行该指令需要 2个机器周期 DJNZR6,DELAY ;R6-1非0转移,执行该指令需要12个状态周期 DJNZR5,DELAY ;R5-1非0转移,执行该指令需要24个振荡周期 RET ;子程序返回,执行该指令需要2个机器周期 说明: R5为延时子程序的输入参数,改变R5的内容可改变延时时间,当R5内容不为0,其51单片机的振荡频率为fosc时,该子程序延时时间t的计算公式为 t =((1+1+(2 × 256 × 256+2 × 256)× R5+2 × R5+2)× 12)÷ fosc 当R5内容为0时,该延时子程序实现最大延时时间,在计算公式中R5取值为256。 3. 代码转换源程序 将存放在内部RAM地址为30H单元中的一个二进制整数转换成相应的BCD码,转换结果从高到低依次存放在70H、71H、72H单元中。 ORG0000H LJMPSTART;程序开始 ORG0030H START: MOVR0,#70H;设置存放结果单元指针 MOVA,30H;将二进制数据传送到A MOVB,#100;将除数100传送到B DIVAB;二进制数据除以100 MOV@R0,A;将商存放到70H(百位)单元中 INCR0;将存放结果单元指针加1 MOVA,#10;将除数10传送到A XCHA,B;将被除数(余数)与除数互换位置 DIVAB;将余数再除以10 图311两数据相加流程 MOV@R0,A;将商存放到71H(十位)单元中 INCR0;将存放结果单元指针加1 MOV@R0,B;将余数存放到72H(个位)单元中 SJMP$;结束,等待中 END 说明: 转换方法为二进制整数除以100所得商为BCD码的百位(最高位),所得余数再除以10后,其商为BCD码的十位,余数为BCD码的个位(最低位)。 4. 多字节无符号数据相加源程序 存放于内部RAM中的两个等字节长度的数据做无符号数相加运算,CPU相加流程如图311所示,通过加法子程序实现加运算操作,其源代码如下。 ORG0100H ADDITION: CLRC LOOP: MOVA, @R0 ADDCA, @R1 MOV @R0,A INC R0 INCR1 DJNZR2,LOOP RET 说明: 加法运算子程序的输入参数为R0、R1、R2。R0为被加数存放在RAM中的地址指针,指向被加数据最低字节的存放位置,同时R0也是相加结果存放在RAM中的地址指针,即相加运算完成后,被加数据存放的位置成为相加结果数据的存放位置; R1为加数存放在RAM中的地址指针,指向加数据最低字节的存放位置; R2为求和两数据所占的字节数,为子程序提供按字节数据相加的次数。 5. 多字节无符号数据相乘源程序 下面的子程序源代码实现两个无符号数据做相乘运算的操作。子程序的输入参数为R4、R3、R2。被乘数为16位数据,存放于R4(高字节)、R3(低字节)中; 乘数为8位数据,存放于R2中; 子程序的输出参数为R7、R6、R5,存放相乘运算的结果; R7为最高字节,R6为次高字节,R5为最低字节。 ORG0100H MULTIPLICATION: MOVA,R2;取乘数存放在A MOVB,R3;取被乘数低字节存放在B MULAB;低字节相乘,第1次乘积 MOVR5,A;存放乘积的低字节数 MOVR6,B;存放乘积的高8位 MOVA,R2;取乘数存放在A MOVB,R4;取被乘数高字节存放在B MULAB;高字节相乘,第2次乘积 ADDA,R6;第1次乘积的高位和第2次乘积的低位相加 MOVR6,A;存放乘积的次高字节 MOVA,B ;乘积的高字节送A ADDCA,#00H;与上次加法的进位相加 MOVR7,A;存放乘积的高字节 RET;子程序返回