第5章 CHAPTER 5 MCS51指令集架构 本章介绍了STC单片机CPU指令系统,主要内容包括寻址模式类型和指令类型和功能。 CPU指令系统反映了8051 CPU的结构。当指令系统确定后,CPU内核的结构就确定了。通过对寻址模式类型、指令类型和功能的学习,进一步掌握STC单片机CPU的结构和接口功能,为后续学习汇编语言和C语言程序设计方法打下基础,同时 才能使所编写的软件程序在运行时达到最高的性能要求。 视频讲解 5.1寻址模式类型 一条机器指令包含两部分,即操作码和操作数。操作码的目的是对被操作对象进行处理。典型地,对被操作对象实现逻辑与或非运算、加减乘除运算等。在机器/汇编语言指令中,将操作对象称为操作数。 在STC 8051单片机中,这些被操作的对象(操作数)可以保存在CPU的内部寄存器、片内Flash程序存储器、片内RAM、片内扩展RAM或者片外存储器中,也可能仅是一个常数(它作为指令的一部分存在)。 因此,就需要预先确定一些规则,一方面使得操作数可以保存在这些区域内; 另一方面,CPU可以找到它们。在STC 8051单片机中,将CPU寻找操作对象(操作数)所保存位置的方式称为寻址模式。 在STC 8051单片机中,操作对象包括立即数、直接位地址、程序地址、直接地址、间接地址、特殊的汇编器符号。这些操作对象和寻址模式相关。 需要说明的是,特殊汇编器符号用来表示8051 CPU的内部功能寄存器,不可以修改这些符号。在8051单片机常用的寄存器符号如下。 (1) A表示8051的累加器ACC。 (2) DPTR表示16位的数据指针,指向外部数据空间或者代码存储空间。 (3) PC表示16位的程序计数器,指向下一条将要执行指令的地址。 (4) C表示进位标志CY。 (5) AB表示A和B寄存器对,用于乘和除操作。 (6) R0~R7表示当前所使用寄存器组内的8个8位通用寄存器。 (7) SP表示堆栈指针。 (8) DPS表示数据指针选择寄存器。 STC15系列单片机采用的是8051 CPU内核,所以其寻址模式和传统的8051单片机是一样的。 1. 立即数寻址模式 一些指令直接加载常数的值,而不是地址。例如指令: MOV A, #3AH 功能: 将8位的十六进制立即数3A送给累加器A,如图5.1所示。 2. 直接寻址模式 操作数由一个直接8位地址域指定。当使用这种模式时,只能访问片内RAM和特殊功能寄存器SFR。例如指令: MOV A,3AH 功能: 将片内RAM中地址为3AH单元内的数据送给累加器A,如图5.2所示。 图5.1立即数寻址模式 图5.2直接寻址模式 注意: 和MOV A,#3AH指令的区别。如果操作数前带“#”符号,则操作数表示的是一个立即数,是立即数寻址模式。而操作数前面不带“#”符号,则操作数表示的是存储器的地址,3A是存储器的地址,表示把存储器地址为3A单元的内容送到累加器A中。 3. 间接寻址模式 由指令指定一个寄存器,该寄存器包含操作数的地址。寄存器R0和R1用来指定8位地址,数据指针寄存器(DPTR)用来指定16位的地址。例如指令: ANL A,@R1 假设累加器A的内容为31H,R1寄存器的内容为60H,即(R1)=60H,则以60H作为存储器的地址,将60H地址单元的内容与累加器A中的数31H进行逻辑与运算,运算结果存放在累加器A中,如图5.3所示。 图5.3间接寻址模式 4. 寄存器寻址模式 某些特定指令用来访问寄存器组中的R0~R7寄存器、累加器A、通用寄存器B、地址寄存器和进位CY。由于这些指令不需要地址域,因此这些指令访问效率更高。例如指令: INC R0 功能: 将寄存器R0的内容加1,再送回R0,如图5.4所示(假设当前寄存器R0中的数为50H)。 5. 相对寻址模式 相对寻址时将程序计数器(PC)中的当前值与指令中第二字节给出的数相加,其结果作为转移指令的目的转移地址。PC中的当前值为基地址,指令第二字节给出的数作为偏移量。由于目的地址是相对于PC中的基地址而言,所以这种寻址方式称为相对寻址。偏移量为带符号的数,范围为-128~+127。这种寻址方式主要用于跳转指令。例如指令: JC 80H 注意: 该指令为两字节,操作码JC占用一字节,80H占用另一字节。 功能: 当进位标志为1时,则进行跳转,如图5.5所示。 图5.4寄存器寻址模式 图5.5相对寻址模式 6. 变址寻址模式 变址寻址模式使用数据指针作为基地址,累加器值作为偏移地址来读取程序Flash存储器。例如 指令: MOVC A,@A+DPTR 功能: 将DPTR和A的内容相加所得到的值作为程序存储器的地址,并将该地址单元的内容送A,如图5.6所示。 图5.6变址寻址模式 7. 位寻址模式 位寻址是对一些内部数据存储器RAM和特殊功能寄存器SFR进行位操作时的寻址模式。在进行位操作时,指令操作数直接给出该位的地址,然后根据操作码的类型对该位进行操作。在这种模式下,操作数是256bit中的某一位。例如指令: MOV C,2BH 图5.7位寻址模式 功能: 把位寻址区位地址为2BH的位状态送进位标志C,如图5.7所示。 思考与练习51: 在STC 8051单片机中,共有种寻址模式。 思考与练习52: 请说明在STC 8051单片机中,操作数可以存放的位置。 思考与练习53: 在STC 8051单片机中,寻址模式是指。 思考与练习54: 参考STC寻址模式和STC单片机CPU指令集,说明下面指令的寻址模式: (1) MOV DPTR,#1234H,寻址模式。 (2) MUL AB,寻址模式。 (3) SETB C,寻址模式。 (4) MOV A,12H,寻址模式。 (5) MOVC A,@A+PC,寻址模式。 (6) LJMP 100H,寻址模式。 (7) MOV A,@R1,寻址模式。 5.2指令类型和功能 STC15系列单片机内的8051 CPU指令集包含111条指令,这些指令与传统的8051指令完全兼容,但是大幅度提高了执行指令的时间效率,具体表现在如下方面。 (1) 采用了STCY5超高速CPU内核,在相同的时钟频率下,速度又比STC早期的IT系列单片机(如STC12系列/STC11系列/STC10系列)快20%。 (2) 典型地,其中INC DPTR和MUL AB指令的执行速度大幅提高24倍。 (3) 在指令集中有22条指令,这些指令可以在一个周期内执行完,平均速度提高8~12倍。 (4) 将111条指令全部执行完一遍所需的时钟周期数为283,而传统的8051单片机将111条指令全部执行完所需要的时钟周期数为1944。 按照所实现的功能,将STC15单片机内8051 CPU指令集分为算术指令、逻辑指令、数据传送指令、布尔指令、程序分支指令。 视频讲解 5.2.1算术指令 算术指令支持直接、间接、寄存器、立即数和寄存器指定指令寻址方式。算术模式用于加、减、乘、除、递增和递减操作。 1. 加法指令 1) ADD A,Rn 该指令将寄存器Rn的内容和累加器A的内容相加,结果保存在累加器A中,如表5.1所示。并设置CY标志、AC标志,以及溢出标志OV。 表5.1ADD A,Rn指令的内容 助记符操作标志机器码字节数周期数 ADD A,Rn(PC)← (PC) + 1 (A)← (A) + (Rn)CY,AC,OV00101rrr11 (1) 当和的第3位和第7位有进位时,分别将AC、CY标志置位,否则清零。 (2) 对于带符号运算数,当和的第7位与第6位中有一位进位,而另一位不产生进位时,溢出标志OV置位,否则清零。或者可以这样说,当两个正数相加时,相加的结果为负数; 或当两个负数相加时,相加的结果为正数时,在这两种情况下设置OV为1。 注意: rrr为寄存器的编号,因此机器码范围是28H~2FH。 【例51】假设累加器A中的数据为C3H,R0寄存器中的数据为AAH。执行指令: ADD A,R0 结果: (A)=6DH,(AC)=0,(CY)=1,(OV)=1。 注意: ()表示内容。 计算过程为 1100,0011 +1010,1010 1,0110,1101 2) ADD A,direct 该指令将直接寻址单元的内容和累加器A的内容相加,结果保存在累加器A中,如表5.2所示。CY、AC、OV标志的设置同上。 表5.2ADD A,direct指令的内容 助记符操作标志操作码字节数周期数 ADD A,direct(PC) ← (PC) + 2 (A) ← (A) + (direct)CY,AC,OV0010010122 注意: 在操作码后面跟着1字节的直接地址。 3) ADD A,@Ri 该指令将间接寻址单元的内容和累加器A的内容相加,结果保存在累加器A中,如表5.3所示。CY、AC、OV标志的设置同上。 表5.3ADD A,@Ri指令的内容 助记符操作标志操作码字节数周期数 ADD A,@Ri(PC)← (PC) + 1 (A)← (A) + ((Ri))CY,AC,OV0010011i12 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 4) ADD A,#data 该指令将一个立即数和累加器A的内容相加,结果保存在累加器A中,如表5.4所示。CY、AC、OV标志的设置同上。 表5.4ADD A,#data指令的内容 助记符操作标志操作码字节数周期数 ADD A,#data(PC)← (PC) + 2 (A)← (A) + dataCY,AC,OV0010010022 注意: 在操作码后面跟着1字节的立即数。 5) ADDC A,Rn 该指令将寄存器Rn的内容与累加器A的内容及进位标志CY的内容相加,结果保存在累加器A中,如表5.5所示。CY、AC、OV标志的设置同上。 表5.5ADDC A,Rn指令的内容 助记符操作标志操作码字节数周期数 ADDC A,Rn(PC)← (PC) + 1 (A)← (A) +(C)+ (Rn)CY,AC,OV00111rrr11 注意: rrr为寄存器的编号,因此机器码范围是38H~3FH。 【例52】假设累加器A中的数据为C3H,R0寄存器中的数据为AAH,进位标志为1时,执行指令: ADDC A,R0 结果: (A)=6EH,(AC)=0,(CY)=1,(OV)=1。 计算过程为 1100,0011 1010,1010 +1 1,0110,1110 6) ADDC A,direct 该指令将直接寻址单元的内容与累加器A的内容及进位标志CY中的内容相加,结果保存在累加器A中,如表5.6所示。CY、AC、OV标志的设置同上。 表5.6ADDC A,direct指令的内容 助记符操作标志操作码字节数周期数 ADDC A,direct(PC)← (PC) + 2 (A)← (A) +(C) + (direct)CY,AC,OV0011010122 注意: 在操作码后面跟着1字节的直接地址。 7) ADDC A,@Ri 该指令将间接寻址单元的内容与累加器A的内容及进位标志CY中的内容相加,结果保存在累加器A中,如表5.7所示。CY、AC、OV标志的设置同上。 表5.7ADDC A,@Ri指令的内容 助记符操作标志操作码字节数周期数 ADDC A,@Ri(PC)← (PC) + 1 (A)← (A) +(C) + ((Ri))CY,AC,OV0011011i12 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 8) ADDC A,#data 该指令将一个立即数与累加器A的内容及进位标志CY中的内容相加,结果保存在累加器A中,如表5.8所示。CY、AC、OV标志的设置同上。 表5.8ADDC A,#data指令的内容 助记符操作标志操作码字节数周期数 ADDC A,#data(PC)← (PC) + 2 (A)← (A) +(C)+ dataCY,AC,OV0011010022 注意: 在操作码后面跟着1字节的立即数。 2. 减法指令 1) SUBB A,Rn 该指令从累加器A中减去寄存器Rn和进位标志CY内的内容,将结果保存在累加器A中,如表5.9所示。 表5.9SUBB A,Rn指令的内容 助记符操作标志操作码字节数周期数 SUBB A,Rn(PC)← (PC) + 1 (A)← (A) - (C) - (Rn)CY,AC,OV10011rrr11 (1) 如果第7位需要一个借位,则设置进位(借位)标志; 否则,清除CY标志。 注意: 如果在执行指令前,已经设置了CY标志,则表示前面的多个步骤需要一个借位。这样,从累加器中减去进位标志以及源操作数。 (2) 如果第3位需要一个借位,则设置AC标志; 否则,清除AC标志。 (3) 如果第6位需要借位,而第7位没有借位; 或者第7位有借位,而第6位没有借位,在这两种情况下都会设置OV标志。或者可以这样说,当减去有符号的整数时,当一个正数减去一个负数,产生一个负数结果时; 或者一个负数减去一个正数时,产生一个正数结果时,设置OV标志。 注意: rrr为寄存器的编号,因此机器码范围是98H~9FH。 【例53】假设累加器A中的数据为C9H,R2寄存器中的数据为54H,进位标志为1时,执行指令: SUBB A,R2 结果: (A)=74H,(AC)=0,(CY)=0,(OV)=1。 计算过程为 1100,1001 0101,0100 -1 0111,0100 2) SUBB A,direct 该指令从累加器A中减去直接寻址单元的内容和进位标志CY的内容,然后结果保存在累加器A中,如表5.10所示。CY、AC、OV标志的设置同上。 表5.10SUBB A,direct指令的内容 助记符操作标志操作码字节数周期数 SUBB A,direct(PC)← (PC) + 2 (A)← (A) - (C) - (direct)CY,AC,OV1001010122 注意: 在操作码后面跟着1字节的直接地址。 3) SUBB A,@Ri 该指令从累加器A中减去间接寻址单元的内容和进位标志CY的内容,然后结果保存在累加器A中,如表5.11所示。CY、AC、OV标志的设置同上。 表5.11SUBB A,@Ri指令的内容 助记符操作标志操作码字节数周期数 SUBB A,@Ri(PC)← (PC) + 1 (A)← (A) - (C) - ((Ri))CY,AC,OV1001011i12 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 4) SUBB A,#data 该指令从累加器A中减去一个立即数和进位标志CY的内容,然后结果保存在累加器A中,如表5.12所示。CY、AC、OV标志的设置同上。 表5.12SUBB A,#data指令的内容 助记符操作标志操作码字节数周期数 SUBB A,#data(PC)← (PC) + 2 (A)← (A) - (C) - dataCY,AC,OV1001010022 注意: 操作码后面跟着1字节的立即数。 3. 递增指令 1) INC A 该指令将累加器A的内容加1,结果保存在累加器A中,如表5.13所示。若累加器A的结果为0xFF,在执行完该指令后,将其内容设置为0。 表5.13INC A指令的内容 助记符操作标志操作码字节数周期数 INC A(PC)← (PC) + 1 (A)← (A) + 1N0000010011 2) INC Rn 该指令将寄存器Rn的内容加1,结果保存在Rn中,如表5.14所示。若Rn的结果为0xFF,在执行完该指令后,将其内容设置为0。 表5.14INC Rn指令的内容 助记符操作标志操作码字节数周期数 INC Rn(PC)← (PC) + 1 (Rn)← (Rn) + 1N00001rrr12 注意: rrr为寄存器的编号,因此机器码是08H~0FH。 3) INC direct 该指令将直接寻址单元的内容加1,结果保存在直接地址单元中,如表5.15所示。若直接地址单元的结果为0xFF,在执行完该指令后,将其内容设置为0。 表5.15INC direct指令的内容 助记符操作标志操作码字节数周期数 INC direct(PC)← (PC) + 2 (direct)← (direct) + 1N0000010123 注意: 在操作码后面跟着1字节的直接地址。 4) INC @Ri 该指令将间接寻址单元的内容加1,结果保存在间接地址单元中,如表5.16所示。若间接地址单元的结果为0xFF,则将其内容设置为0。 表5.16INC @Ri指令的内容 助记符操作标志操作码字节数周期数 INC @Ri(PC)← (PC) + 1 ((Ri)) ← ((Ri)) + 1N0000011i13 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 5) INC DPTR 该指令将DPTR的内容加1,结果保存在DPTR中,如表5.17所示。若DPTR的结果为0xFFFF,在执行完该指令后,将其内容设置为0x0000。 表5.17INC DPTR指令的内容 助记符操作标志操作码字节数周期数 INC DPTR(PC)← (PC) + 1 (DPTR)← (DPTR) + 1N1010001111 【例54】假设寄存器R0中的数据为7EH,内部RAM地址为7EH和7FH单元的数据分别为FFH和40H,即(7E)=FFH,(7F)=40H,则当执行指令: INC @R0; 内部RAM地址为7EH单元的内容加1,变成00H INC R0;寄存器R0中的数据变为7FH INC @R0;内部RAM地址为7FH单元的内容加1,变成41H 结果: (R0)=7FH,内部RAM地址为7EH和7FH单元的数据变为00H和41H。 4. 递减指令 1) DEC A 该指令将累加器A的内容减1,结果保存在累加器A中,如表5.18所示。如果累加器A中的内容为0,在执行完该指令后,变为0xFF。 表5.18DEC A指令的内容 助记符操作标志操作码字节数周期数 DEC A(PC)← (PC) + 1 (A) ← (A) -1N0001010011 2) DEC Rn 该指令将寄存器Rn的内容减1,结果保存在寄存器Rn中,如表5.19所示。如果Rn的内容为0,在执行完该指令后,变为0xFF。 表5.19DEC Rn指令的内容 助记符操作标志操作码字节数周期数 DEC Rn(PC)← (PC) + 1 (Rn)← (Rn)-1N00011rrr12 注意: rrr为寄存器的编号,因此机器码范围是18H~1FH。 3) DEC direct 该指令将直接寻址单元的内容减1,结果保存在直接地址单元中,如表5.20所示。如果直接寻址单元的内容为0,在执行完该指令后,变为0xFF。 表5.20DEC direct指令的内容 助记符操作标志操作码字节数周期数 DEC direct(PC)← (PC) + 2 (direct) ← (direct)-1N0001010123 注意: 在操作码后面跟着1字节的直接地址。 4) DEC @Ri 该指令将间接寻址单元的内容减1,结果保存在间接地址单元中,如表5.21所示。如果间接寻址单元的内容为0,在执行完该指令后,变为0xFF。 表5.21DEC @Ri指令的内容 助记符操作标志操作码字节数周期数 DEC @Ri(PC)← (PC) + 1 ((Ri)) ← ((Ri))-1N0001011i13 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 【例55】假设寄存器R0中的数据为7FH,内部RAM地址为7EH和7FH单元的数据分别为40H和00H,即(7F)=00H,(7E)=40H,则当执行指令: DEC @R0 ; 内部RAM地址为7FH单元的内容减1,变成FFH DEC R0 ;寄存器R0中的数据变为7EH DEC @R0 (此时的R0中的数据应该是40H) ; 内部RAM地址为7EH单元的内容减1,变成3FH 结果: (R0)=7EH,内部RAM地址为7EH和7FH单元的数据变为FFH和3FH。 5. 乘法指令 MUL AB指令将累加器A和寄存器B中的两个无符号8位二进制数相乘,所得的16位乘积的低8位结果保存在累加器A中,高8位结果保存在寄存器B中,如表5.22所示。 如果乘积大于255,则溢出标志OV置1; 否则OV清零。在执行该指令时,总是清除进位标志CY。 表5.22MUL AB指令的内容 助记符操作标志操作码字节数周期数 MUL AB(PC)← (PC) + 1 (A)← (A) × (B)结果的第7位~第0位 (B)← (A) × (B)结果的第15位~第8位CY,OV1010010012 【例56】假设累加器A中的数据为(80)10=50H,寄存器B中的数据为(160)10=A0H,则执行指令: MUL AB 结果: 乘积为(12800)10=3200H,(A)=00H,(B)=32H,(CY)=0,(OV)=1。 计算过程为 6. 除法指令 DIV AB指令用累加器A中的无符号整数除以寄存器B中无符号整数,所得的商保存在累加器A中,余数保存在寄存器B中,如表5.23所示。当除数(B寄存器的内容)为0时,结果不定,溢出标志OV置1。在执行该指令时,清除进位标志CY。 表5.23DIV AB指令的内容 助记符操作标志操作码字节数周期数 DIV AB(PC)← (PC) + 1 (A)158 ← (A)/(B) (B)70 ← (A)/(B) CY,OV1000010016 【例57】假设累加器A中的数据为(251)10=FBH,寄存器B中的数据为(18)10=12H,则执行指令: DIV AB 结果: (A)=0DH,(B)=11H,(CY)=0,(OV)=0。 计算过程为 7. BCD调整指令 DA A指令的功能是对BCD码的加法结果进行调整。两个压缩型BCD码按十进制数相加后,需经此指令的调整才能得到压缩型BCD码的和数,如表5.24所示。 表5.24DA A指令的内容 助记符操作标志操作码字节数周期数 DA A(PC)← (PC) + 1 如果{[(A30) > 9] ∨ [(AC) = 1]},则 (A30) ← (A30) + 6 如果{[(A74) > 9] ∨ [(C) = 1]},则 (A74) ← (A74) + 6CY1101010013 本指令是根据A的最初数值和程序状态字PSW的状态,决定对A进行加06H、60H或66H操作的。 注意: 如果前面没有使用加法运算,则不能直接使用DA指令。此外,如果前面执行的是减法运算,则DA指令也不起任何作用。 【例58】假设累加器A中的数据为56H,表示十进制数56的BCD码。寄存器R3的内容为67H,表示十进制数67的BCD码。进位标志为1,则执行指令: ADDC A,R3//累加器A的结果为BEH,(AC)=0,(CY)=0 DA A //表示十进制数的124 结果表示为(A)=124。 注意: 因为在执行完ADDC指令后,(A)=BEH。 (A)30>9,所以(A) 30+6→(A) 30=4H,向第4位有进位。 (A)74>9,所以(A) 74+6+进位→(A) 74=2H,最高位有进位。 思考与练习55: 假定(A)=66H,(R0)=55H,(55H)=FFH,执行指令: ADD A, @R0 (A)=,(CY)=,(OV)=。 思考与练习56: 如果(A)=60H,(B)=73H,(CY)=1时,执行指令: ADDC A, B (A)=,(CY)=,(OV)=。 思考与练习57: 如果(A)=3DH,(B)=4EH,执行指令: MUL AB (A)=,(B)=。 视频讲解 5.2.2逻辑指令 逻辑指令执行布尔操作,如逻辑与、逻辑或、逻辑异或操作,对累加器内容进行旋转,累加器半字交换。 1. 逻辑与指令 1) ANL A, Rn 该指令将累加器A的内容和寄存器Rn的内容做逻辑与操作,结果保存在累加器A中,如表5.25所示。 表5.25ANL A,Rn指令的内容 助记符操作标志操作码字节数周期数 ANL A,Rn(PC)← (PC) + 1 (A)← (A)∧(Rn)N01011rrr11 注意: rrr为寄存器的编号,因此机器码范围是58H~5FH。 【例59】假设累加器A中的数据为C3H,寄存器R0的内容为55H,则执行指令: ANL A,R0 结果: 累加器A中的数据为41H。 注意: 计算过程为 11000011 ∧01010101 01000001 【例510】执行指令 ANL P1, #01110011B 结果: 将端口1的第7位、第3位和第2位清零。 2) ANL A, direct 该指令将累加器A的内容和直接寻址单元的内容做逻辑与操作,结果保存在累加器A中,如表5.26所示。 表5.26 ANL A,direct指令的内容 助记符操作标志操作码字节数周期数 ANL A,direct(PC)← (PC) + 2 (A)← (A)∧(direct)N0101010122 注意: 在操作码后面跟着1字节的直接地址。 3) ANL A, @Ri 该指令将累加器A的内容和间接寻址单元中的内容做逻辑与操作,结果保存在累加器A中,如表5.27所示。 表5.27ANL A,@Ri指令的内容 助记符操作标志操作码字节数周期数 ANL A,@Ri(PC)← (PC) + 1 (A)← (A)∧((Ri))N0101011i12 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 4) ANL A, #data 该指令将累加器A的内容和立即数做逻辑与操作,结果保存在累加器A中,如表5.28所示。 表5.28ANL A,#data指令的内容 助记符操作标志操作码字节数周期数 ANL A,#data(PC)← (PC) + 2 (A)← (A) ∧ dataN0101010022 注意: 在操作码后面跟着1字节的立即数。 5) ANL direct, A 该指令将累加器A的内容和直接寻址单元的内容做逻辑与操作,结果保存在直接寻址单元中,如表5.29所示。 表5.29ANL direct,A指令的内容 助记符操作标志操作码字节数周期数 ANL direct, A(PC)← (PC) + 2 (direct)← (direct) ∧ (A)N0101001023 注意: 在操作码后面跟着1字节的直接地址。 6) ANL direct, #data 该指令对立即数和直接寻址单元的内容做逻辑与操作,结果保存在直接寻址单元中,如表5.30所示。 表5.30ANL direct,#data指令的内容 助记符操作标志操作码字节数周期数 ANL direct, #data(PC)← (PC) + 3 (direct) ← (direct) ∧ dataN0101001133 注意: 在操作码后面跟着1字节的直接地址和1字节的立即数。 2. 逻辑或指令 1) ORL A, Rn 该指令将累加器A的内容和寄存器Rn中内容做逻辑或操作,结果保存在累加器A中,如表5.31所示。 表5.31ORL A,Rn指令的内容 助记符操作标志操作码字节数周期数 ORL A,Rn(PC)← (PC) + 1 (A)← (A) ∨ (Rn)N01001rrr11 注意: rrr为寄存器的编号,因此机器码范围是48H~4FH。 【例511】假设累加器A中的数据为C3H,寄存器R0的内容为55H,则执行指令: ORL A,R0 结果: 累加器A中的数据为D7H。 计算过程为 11000011 ∨01010101 11010111 【例512】执行指令 ORL P1, #00110010B 结果: 将端口1的第5位、第4位和第1位置1。 2) ORL A, direct 该指令将累加器A的内容和直接寻址单元的内容做逻辑或操作,结果保存在累加器A中,如表5.32所示。 表5.32ORL A,direct指令的内容 助记符操作标志操作码字节数周期数 ORL A,direct(PC)← (PC) + 2 (A)← (A) ∨ (direct)N0100010122 注意: 在操作码后面跟着1字节的直接地址。 3) ORL A, @Ri 该指令将累加器A的内容和间接寻址单元中内容做逻辑或操作,结果保存在累加器A中,如表5.33所示。 表5.33ORL A,@Ri指令的内容 助记符操作标志操作码字节数周期数 ORL A,@Ri(PC)← (PC) + 1 (A)← (A) ∨ ((Ri))N0100011i12 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 4) ORL A, #data 该指令将累加器A的内容和立即数做逻辑或操作,结果保存在累加器A中,如表5.34所示。 表5.34ORL A,#data指令的内容 助记符操作标志操作码字节数周期数 ORL A,#data(PC)← (PC) + 2 (A)← (A) ∨ dataN0100010022 注意: 在操作码后面跟着1字节的立即数。 5) ORL direct,A 该指令将直接寻址单元的内容和累加器A的内容做逻辑或操作,结果保存在直接寻址单元中,如表5.35所示。 表5.35ORL direct,A指令的内容 助记符操作标志操作码字节数周期数 ORL direct,A(PC) ← (PC) + 2 (direct) ← (direct)∨ (A)N0100001023 注意: 在操作码后面跟着1字节的直接地址。 6) ORL direct, #data 该指令将直接寻址单元中内容和立即数做逻辑或操作,结果保存在直接寻址单元中,如表5.36所示。 表5.36ORL direct,#data指令的内容 助记符操作标志操作码字节数周期数 ORL direct,#data(PC)← (PC) + 3 (direct)← (direct) ∨ dataN0100001133 注意: 在操作码后面跟着1字节的直接地址和1字节的立即数。 3. 逻辑异或指令 1) XRL A,Rn 该指令将累加器A的内容和寄存器Rn的内容做逻辑异或操作,结果保存在累加器A中,如表5.37所示。 表5.37XRL A,Rn指令的内容 助记符操作标志操作码字节数周期数 XRL A,Rn(PC)← (PC) + 1 (A)← (A) (Rn)N01101rrr11 注意: rrr为寄存器的编号,因此机器码范围是68H~6FH。 【例513】假设累加器A中的数据为C3H,寄存器R0的内容为AAH,则执行指令: XRL A,R0 结果: 累加器A中的数据为69H。 计算过程为 11000011 10101010 01101001 【例514】执行指令 XRL P1, #00110001B 结果: 将端口1的第5位、第4位和第0位取反。 2) XRL A, direct 该指令将累加器A的内容和直接寻址单元的内容做逻辑异或操作,结果保存在累加器A中,如表5.38所示。 表5.38XRL A,direct指令的内容 助记符操作标志操作码字节数周期数 XRL A,direct(PC)← (PC) + 2 (A)← (A) (direct)N0110010122 注意: 在操作码后面跟着1字节的直接地址。 3) XRL A,@Ri 该指令将累加器A的内容和间接寻址单元的内容做逻辑异或操作,结果保存在累加器A中,如表5.39所示。 表5.39XRL A,@Ri指令的内容 助记符操作标志操作码字节数周期数 XRL A,@Ri(PC)← (PC) + 1 (A)← (A) ((Ri))N0110011i12 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 4) XRL A, #data 该指令将累加器A的内容和一个立即数做逻辑异或操作,结果保存在累加器A中,如表5.40所示。 表5.40XRL A,#data指令的内容 助记符操作标志操作码字节数周期数 XRL A,#data(PC)← (PC) + 2 (A)← (A) dataN0110010022 注意: 在操作码后面跟着1字节的立即数。 5) XRL direct, A 该指令将直接寻址单元的内容和累加器A的内容做逻辑异或操作,结果保存在直接寻址的单元中,如表5.41所示。 表5.41XRL direct,A指令的内容 助记符操作标志操作码字节数周期数 XRL direct, A(PC)← (PC) + 2 (direct)← (direct) (A)N0110001023 注意: 在操作码后面跟着1字节的直接地址。 6) XRL direct, #data 该指令将直接寻址的内容和一个立即数做逻辑异或操作,结果保存在直接寻址的单元中,如表5.42所示。 表5.42XRL direct,#data指令的内容 助记符操作标志操作码字节数周期数 XRL direct,#data(PC)← (PC) + 3 (direct)← (direct) dataN0110001133 注意: 在操作码后面跟着1字节的直接地址和1字节的立即数。 4. 清除指令 CLR A指令将累加器A中的各位清零,如表5.43所示。 表5.43CLR A指令的内容 助记符操作标志操作码字节数周期数 CLR A(PC)← (PC) + 1 (A)← 0N1110010011 【例515】假设累加器A中的数据为5CH,则执行指令: CLR A 结果: (A)=00H。 5. 取反指令 CPL A指令将累加器A按位取反,即将累加器A各位中的逻辑1变成逻辑0,逻辑0变成逻辑1,如表5.44所示。 表5.44CPL A指令的内容 助记符操作标志操作码字节数周期数 CPL A(PC)← (PC) + 1 (A)← ()N1111010011 【例516】假设P1端口的数据为5BH,则执行指令: CPL P1.1 CPL P1.2 结果: 将P1端口设置为5DH=01011101B。 6. 移位指令 1) RL A 该指令将累加器A中的内容循环左移,如表5.45所示。 表5.45RL A指令的内容 助记符操作标志操作码字节数周期数 RL A(PC)← (PC) + 1 (An + 1) ← (An),n = 0~6 (A0) ← (A7)N0010001111 【例517】假设累加器A的数据为C5H(11000101B),则执行指令: RL A 结果: 累加器A的数据变成8BH=10001011B。 2) RLC A 该指令将累加器A的内容和进位标志CY一起循环左移,如表5.46所示。 表5.46RLC A指令的内容 助记符操作标志操作码字节数周期数 RLC A(PC)← (PC) + 1 (An + 1) ← (An),n = 0~6 (A0) ← (CY) (CY) ← (A7)CY0011001111 【例518】假设累加器A的数据为C5H(11000101B),进位标志(CY)=0,则执行指令: RLC A 结果: 累加器A的内容变成8AH=10001010B,进位标志(CY)=1。 3) RR A 该指令将累加器A的内容循环右移,如表5.47所示。 表5.47RR A指令的内容 助记符操作标志操作码字节数周期数 RR A(PC)← (PC) + 1 (An) ← (An + 1),n = 0~6 (A7) ← (A0)N0000001111 【例519】假设累加器A的数据为C5H(11000101B),则执行指令: RR A 结果: 累加器A的内容变成E2H=11100010B。 4) RRC A 该指令将累加器A的内容和进位标志CY一起循环右移,如表5.48所示。 表5.48RRC A指令的内容 助记符操作标志操作码字节数周期数 RRC A(PC)← (PC) + 1 (An) ← (An + 1),n = 0~6 (A7) ← (CY) (CY) ← (A0)CY0001001111 【例520】假设累加器A的数据为C5H(11000101B),进位标志(CY)=0,则执行指令: RRC A 结果: 累加器A的内容变成62H=01100010B,进位标志(CY)=1。 7. 半字节交换指令 SWAP A指令将累加器A中的半字节互换,即将累加器A的高、低半字节互换,如表5.49所示。 表5.49SWAP A指令的内容 助记符操作标志操作码字节数周期数 SWAP A(PC)← (PC) + 1 (A30) ← (A74) (A74) ← (A30)N1100010011 【例521】假设累加器A的数据为C5H(11000101B),则执行指令: SWAP A 结果: 累加器A的内容变成5CH=01011100B。 思考与练习58: 如果(A)=AAH,(R0)=55H,则 (1) 执行指令 ANL A,R0 (A)=。 (3) 执行指令 XRL A,R0 (A)=。 (2) 执行指令 ORL A,R0 (A)=。 (4) 执行指令 RL A (A)=。 视频讲解 5.2.3数据传送指令 STC单片机中的数据传送指令包括数据传输指令、堆栈操作指令和数据交换指令。 1. 数据传输指令 STC单片机中的数据传输指令包括内部数据传输指令、外部数据传输指令和查找表传输指令。 1) 内部数据传输指令 该类型数据传输指令是在任何两个内部RAM或者SFR间实现数据传输。这些指令使用 直接、间接、寄存器和立即数寻址。 (1) MOV A,Rn 该指令将寄存器Rn中的内容复制到累加器A中,且Rn的内容不发生变化,如表5.50所示。 表5.50MOV A,Rn指令的内容 助记符操作标志操作码字节数周期数 MOV A, Rn(PC)← (PC) + 1 (A)← (Rn)N11101rrr11 注意: rrr为寄存器的编号,因此机器码范围是E8H~EFH。 (2) MOV A,direct 该指令将直接寻址单元的内容复制到累加器A中,且直接寻址单元的内容不发生变化,如表5.51所示。 表5.51MOV A,direct指令的内容 助记符操作标志操作码字节数周期数 MOV A, direct(PC)← (PC) + 2 (A)← (direct)N1110010122 注意: 在操作码后面跟着1字节的直接地址。 (3) MOV A,@Ri 该指令将间接寻址单元中的内容复制到累加器A中,且间接寻址单元的内容不发生变化,如表5.52所示。 表5.52MOV A,@Ri指令的内容 助记符操作标志操作码字节数周期数 MOV A, @Ri(PC)← (PC) + 1 (A)← ((Ri))N1110011i12 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 (4) MOV A,#data 该指令将立即数复制到累加器A中,且立即数的内容不发生变化,如表5.53所示。 表5.53MOV A,#data指令的内容 助记符操作标志操作码字节数周期数 MOV A, #data(PC)← (PC) + 2 (A)← dataN0111010022 注意: 在操作码后面跟着1字节的立即数。 (5) MOV Rn, A 该指令将累加器A的内容复制到寄存器Rn中,且累加器A的内容不发生变化,如表5.54所示。 表5.54MOV Rn,A指令的内容 助记符操作标志操作码字节数周期数 MOV Rn, A(PC)← (PC) + 1 (Rn)← (A)N11111rrr11 注意: rrr为寄存器的编号,因此机器码范围是F8H~FFH。 (6) MOV Rn, direct 该指令将直接寻址单元的内容复制到寄存器Rn中,且直接寻址单元的内容不发生变化,如表5.55所示。 表5.55MOV Rn,direct指令的内容 助记符操作标志操作码字节数周期数 MOV Rn, direct(PC)← (PC) + 2 (Rn)← (direct)N10101rrr23 注意: rrr为寄存器的编号,因此机器码范围是A8H~AFH; 在操作码后面跟着1字节的直接地址。 (7) MOV Rn, #data 该指令将立即数复制到寄存器Rn中,且立即数的内容不发生变化,如表5.56所示。 表5.56MOV Rn,#data指令的内容 助记符操作标志操作码字节数周期数 MOV Rn, #data(PC)← (PC) + 2 (Rn)← dataN01111rrr22 注意: rrr为寄存器的编号,因此机器码范围是78H~7FH; 在操作码后面跟着1字节的立即数。 (8) MOV direct, A 该指令将累加器A的内容复制到直接寻址单元中,且累加器A的内容不发生变化,如表5.57所示。 表5.57MOV direct,A指令的内容 助记符操作标志操作码字节数周期数 MOV direct,A(PC)← (PC) + 2 (direct)← (A)N1111010122 注意: 在操作码后面跟着1字节的直接地址。 (9) MOV direct, Rn 该指令将寄存器Rn的内容复制到直接寻址单元中,且Rn的内容不发生变化,如表5.58所示。 表5.58MOV direct,Rn指令的内容 助记符操作标志操作码字节数周期数 MOV direct, Rn(PC)← (PC) + 2 (direct)← (Rn)N10001rrr22 注意: rrr为寄存器的编号,因此机器码范围是88H~8FH; 在操作码后面跟着1字节的直接地址。 (10) MOV direct, direct 该指令将直接寻址单元的内容复制到另一个直接寻址单元中,且源直接寻址单元的内容不发生变化,如表5.59所示。 表5.59MOV direct,direct指令的内容 助记符操作标志操作码字节数周期数 MOV direct, direct(PC) ← (PC) + 3 (direct) ← (direct)N1000010133 注意: 在操作码后面跟着两字节的直接地址,一个是源操作数地址,另一个是目的操作数地址。 (11) MOV direct, @Ri 该指令将间接寻址单元的内容复制到直接寻址单元中,且间接寻址单元的内容不发生变化,如表5.60所示。 表5.60MOV direct,@Ri指令的内容 助记符操作标志操作码字节数周期数 MOV direct, @Ri(PC)← (PC) + 2 (direct)← ((Ri))N1000011i23 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。在操作码后面跟着1字节的直接地址。 (12) MOV direct, #data 该指令将立即数复制到直接寻址单元中,且立即数的内容不发生变化,如表5.61所示。 表5.61MOV direct,#data指令的内容 助记符操作标志操作码字节数周期数 MOV direct,#data(PC) ← (PC) + 3 (direct) ← dataN0111010133 注意: 在操作码后面跟着1字节的直接地址和1字节的立即数。 (13) MOV @Ri, A 该指令将累加器A的内容复制到间接寻址的单元中,且累加器A的内容不发生变化,如表5.62所示。 表5.62MOV @Ri,A指令的内容 助记符操作标志操作码字节数周期数 MOV @Ri,A(PC)← (PC) + 1 ((Ri))← (A)N1111011i12 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 (14) MOV @Ri, direct 该指令将直接寻址单元的内容复制到间接寻址的寄存器中,且直接寻址寄存器内容不发生变化,如表5.63所示。 表5.63MOV @Ri,direct指令的内容 助记符操作标志操作码字节数周期数 MOV @Ri, direct(PC)← (PC) + 2 ((Ri))← (direct)N1010011i23 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。在操作码后面跟着1字节的直接地址。 (15) MOV @Ri, #data 该指令将立即数内容复制到间接寻址单元中,且立即数的内容不发生变化,如表5.64所示。 表5.64MOV @Ri,#data指令的内容 助记符操作标志操作码字节数周期数 MOV @Ri, #data(PC)← (PC) + 2 ((Ri))← dataN0111011i22 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。在操作码后面跟着1字节的立即数。 (16) MOV DPTR,#data16 该指令将一个16位的立即数复制到数据指针寄存器DPTR中,且16位立即数的内容不发生变化,如表5.65所示。 表5.65MOV DPTR,#data16指令的内容 助记符操作标志操作码字节数周期数 MOV DPTR,#data16(PC)← (PC) + 3 DPH← data158 DPL← data70N1001000033 注意: 在操作码后面跟着两字节(16位)的立即数。 【例522】假设内部RAM地址为30H的单元的内容为40H,而40H单元的内容为10H。端口1的数据为CAH(11001010B),则执行指令: MOV R0,#30H ;将立即数30H送到寄存器R0,(R0)=30H MOV A,@R0 ;将30H作为指向内部RAM的地址,内部RAM地址为30H ;单元的内容40H送到累加器A中 MOV R1,A ;将累加器A的内容40H送到寄存器R1中,(R1)=40H MOV B,@R1 ;将40H作为指向内部RAM的地址,内部RAM地址为40H ;单元的内容10H送到寄存器B中 MOV @R1,P1 ;将P1端口的内容送到R1寄存器所指向的内部RAM的 ;地址单元中,即内部RAM地址为40H的单元的内容变为CAH MOV P2,P1 ;将P1端口的内容送到P2端口中,P2端口的内容变为CAH 2) 外部数据传输指令 该类型传输指令是在累加器和8051片内扩展RAM和外部扩展RAM地址空间实现数据传输,这种传输只能使用 MOVX指令。 (1) MOVX A,@Ri 该指令将外部数据存储区的1字节的内容复制到累加器A中。8位外部数据存储区地址由R0或R1确定,且外部数据存储器单元的内容不发生变化,如表5.66所示。 表5.66MOVX A,@Ri指令的内容 助记符操作标志操作码字节数周期数 MOVX A,@Ri(PC)← (PC) + 1 (A)←((Ri))N1110001i13 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 【例523】假设有一个时分复用地址/数据线的外部RAM存储器,容量为256B,该存储器连接到STC单片机的P0端口上,端口P3用于提供外部RAM所需要的控制信号。端口P1和P2用作通用输入/输出端口。R0寄存器和R1寄存器中的数据分别为12H和34H,外部RAM地址为34H的单元内容为56H,执行指令: MOVX A,@R1;将外部RAM地址为34H单元的内容56H送到累加器A MOVX @R0,A;将累加器A的内容56送到外部RAM地址为12H的单元中 (2) MOVX A,@DPTR 该指令将外部数据存储区的1字节的内容复制到累加器A中。16位外部数据存储区单元的地址由DPTR寄存器确定,且外部数据存储器单元的内容不发生变化,如表5.67所示。 表5.67MOVX A,@DPTR指令的内容 助记符操作标志操作码字节数周期数 MOVX A, @DPTR(PC)← (PC) + 1 (A)← (DPTR)N1110000012 (3) MOVX @Ri, A 该指令将累加器A的内容复制到外部数据存储单元中。8位外部数据存储区地址由R0或R1确定,且累加器A中的内容不发生变化,如表5.68所示。 表5.68MOVX @Ri,A指令的内容 助记符操作标志操作码字节数周期数 MOVX @Ri, A(PC)← (PC) + 1 ((Ri))← (A)N1111001i14 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 (4) MOVX @DPTR,A 该指令将累加器A的内容复制到外部数据存储单元中。16位外部数据存储区单元的地址由DPTR寄存器确定,且累加器A中的内容不发生变化,如表5.69所示。 表5.69MOVX @DPTR,A指令的内容 助记符操作标志操作码字节数周期数 MOVX @DPTR, A(PC)← (PC) + 1 (DPTR)← (A)N1111000013 3) 查找表传输指令 只在累加器和程序存储器之间实现数据传输,这种传输只能使用MOVC指令。 (1) MOVC A,@A+DPTR 该指令将数据指针寄存器DPTR和累加器A的内容相加所得到的存储器地址单元的内容复制到累加器A中,如表5.70所示。 表5.70MOVC A,@A+DPTR指令的内容 助记符操作标志操作码字节数周期数 MOVC A,@A+DPTR(PC)← (PC) + 1 (A)← ((A) + (DPTR))N1001001115 【例524】假设累加器A的值在0~4,下面的子程序将累加器A中的值转换为用DB伪指令定义的4个值之一: REL_PC: INC A MOVC A,@A+PC RET DB 66H DB 77H DB 88H DB 99H 如果在调用该子程序之前累加器的值为02H,执行完该子程序后,累加器的值变为88H。MOVC指令之前的INC A指令是为了在查表时跨越RET而设置的。如果MOVC和表格之间被多字节隔开,则为了正确地读取表格,必须将相应的字节数预先加到累加器A上。 (2) MOVC A,@A+PC 该指令将程序计数器PC和累加器A的内容相加所得到的存储器地址单元的内容复制到累加器A中,如表5.71所示。 表5.71MOVC A,@A+PC指令的内容 助记符操作标志操作码字节数周期数 MOVC A,@A+PC(PC)← (PC) + 1 (A)← ((A) + (PC))N1000001114 2. 堆栈操作指令 1) POP direct 该指令将堆栈指针SP所指向栈顶的内容保存到直接寻址单元中,然后执行(SP)-1→(SP)的操作,此操作不影响标志位,如表5.72所示。 表5.72POP direct指令的内容 助记符操作标志操作码字节数周期数 POP direct(PC)← (PC) + 2 (direct)← ((SP)) (SP)← (SP) - 1N1101000022 注意: 在操作码后面跟着1字节的直接地址。 【例525】假设堆栈指针的初值为32H,内部RAM地址30H~32H单元的数据分别为20H、23H和01H,则执行指令: POP DPH POP DPL 结果: 堆栈指针的值变成30H,(DPH)=01H,(DPL)=23H。 如果继续执行指令: POP SP 则在这种特殊情况下,在写入出栈数据20H之前,栈指针减小到2FH,然后再随着20H的写入,(SP)=20H。 2) PUSH direct 该指令将堆栈指针(SP)+1→(SP)指向栈顶单元,将直接寻址单元的内容送入SP所指向的堆栈空间,此操作不影响标志位,如表5.73所示。 表5.73PUSH direct指令的内容 助记符操作标志操作码字节数周期数 PUSH direct(PC)← (PC) + 2 (SP)← (SP) + 1 ((SP))← (direct)N1100000023 注意: 在操作码后面跟着1字节的直接地址。 【例526】假设在进入中断服务程序之前堆栈指针的值为09H,数据指针DPTR的值为0123H,则执行下面的指令: PUSH DPL PUSH DPH 结果: 堆栈指针变成0BH,并把数据23H和01H分别保存到内部RAM的0AH和0BH的存储单元中。 3. 数据交换指令 1) XCH A,Rn 该指令将累加器A的内容和寄存器Rn中的内容互相交换,如表5.74所示。 表5.74XCH A,Rn指令的内容 助记符操作标志操作码字节数周期数 XCH A,Rn(PC)← (PC) + 1 (A) (Rn)N11001rrr12 注意: rrr为寄存器的编号,因此机器码范围是C8H~CFH。 2) XCH A, direct 该指令将累加器A的内容和直接寻址单元的内容互相交换,如表5.75所示。 表5.75XCH A,direct指令的内容 助记符操作标志操作码字节数周期数 XCH A,direct(PC)← (PC) + 2 (A) (direct)N1100010123 注意: 在操作码后面跟着1字节的直接地址。 3) XCH A,@Ri 该指令将累加器A的内容和间接寻址的内容互相交换,如表5.76所示。 表5.76XCH A,@Ri指令的内容 助记符操作标志操作码字节数周期数 XCH A,@Ri(PC)← (PC) + 1 (A) ((Ri))N1100011i 13 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 【例527】假设R0的内容为地址20H,累加器A的内容为3FH。内部RAM地址为20H单元的内容为75H,执行指令: XCHA,@R0 结果: 执行该指令后,将20H所指向的内部RAM的单元的数据75H和累加器A的内容3FH进行交换,结果是累加器A的内容变成75H,而内部RAM地址为20H单元的内容变成3FH。 4) XCHD A,@Ri 该指令将累加器A的内容和间接寻址单元内容的低半字节互相交换,如表5.77所示。 表5.77XCHD A,@Ri指令的内容 助记符操作标志操作码字节数周期数 XCHD A,@Ri(PC)← (PC) + 1 (A30)  ((Ri)30)N1101011i13 注意: i表示R0或者R1。当i=0时,表示R0寄存器; 当i=1时,表示R1寄存器。 【例528】假设寄存器R0的内容为20H,累加器A的内容为36H,内部RAM地址为20H的单元内容为75H,执行指令: XCHD A,@R0 结果: 将20H所指向内部RAM单元的数据75H和累加器A的内容36H的低4位数据进行交换,结果是累加器A的内容变成35H,而内部RAM地址为20H单元的内容变成76H。 思考与练习59: 假设(30H)=40H,(31H)=5DH,(SP)=15H,则执行下面的指令: PUSH 30H PUSH 31H 的目的是,(SP)=。 视频讲解 5.2.4布尔指令 8051单片机有独立的位可寻址区域。它有128比特的位可寻址的RAM和SFR。 1. 清除指令 1) CLR bit 该指令将目的比特位清零,如表5.78所示。 表5.78CLR bit指令的内容 助记符操作标志操作码字节数周期数 CLR bit(PC)← (PC) + 2 (bit)← 0N1100001023 注意: 在操作码后面跟着1字节的位地址。 【例529】假设端口P1的数据为5DH(01011101B),执行指令: CLRP1.2 结果: 端口P1的内容为59H(01011001B)。 2) CLR C 该指令将进位标志位CY清零,如表5.79所示。 表5.79CLR C指令的内容 助记符操作标志操作码字节数周期数 CLR C(PC)← (PC) + 1 (C)← 0CY1100001111 2. 设置指令 1) SETB bit 该指令将目标比特位置1,如表5.80所示。 表5.80SETB bit指令的内容 助记符操作标志操作码字节数周期数 SETB bit(PC)← (PC) + 2 (bit)← 1N1101001023 注意: 在操作码后面跟着一字节的位地址。 2) SETB C 该指令将进位标志CY置1,如表5.81所示。 表5.81SETB C指令的内容 助记符操作标志操作码字节数周期数 SETB C(PC)← (PC) + 1 (C)← 1CY1101001111 【例530】假设端口P1的数据为34H(00110100B),执行指令: SETB C SETB P1.0 结果: 进位标志(CY)=1,端口P1的数据变成为35H(00110101B)。 3. 取反指令 1) CPL bit 该指令将目标比特位取反,如表5.82所示。 表5.82CPL bit指令的内容 助记符操作标志操作码字节数周期数 CPL bit(PC)← (PC) + 2 (bit)← (bit)N1011001023 注意: 在操作码后面跟着1字节的位地址。 【例531】假设端口P1的数据为5BH(01011011B),执行指令: CPL P1.1 CPL P1.2 结果: 端口P1的数据变成为5DH(01011101B)。 2) CPL C 该指令将进位标志CY取反。如果CY为1,执行该指令后CY为0; 反之亦然,如表5.83所示。 表5.83CPL C指令的内容 助记符操作标志操作码字节数周期数 CPL C(PC)← (PC) + 1 (C)← ()CY1011001111 4. 逻辑与指令 1) ANL C, bit 该指令对进位标志CY和一个比特位做逻辑与操作,结果保存在CY中,如表5.84所示。 表5.84ANL C,bit指令的内容 助记符操作标志操作码字节数周期数 ANL C, bit(PC)← (PC) + 2 (CY) ← (CY) ^ (bit)CY1000001022 注意: 在操作码后面跟着1字节的位地址。 2) ANL C, /bit 该指令对进位标志CY和一个比特位取反后做逻辑与操作,结果保存在CY中,如表5.85所示。 表5.85ANL C,/bit指令的内容 助记符操作标志操作码字节数周期数 ANL C, /bit(PC)← (PC) + 2 (CY) ← (CY) ^ (bit)CY1011000022 注意: 在操作码后面跟着1字节的位地址。 【例532】假设P1端口的第0位为1,且累加器A的第7位为1,同时溢出标志OV的内容为0,执行指令: MOV C,P1.0;进位标志CY设置为1 ANL C,ACC.7;进位标志CY设置为1 ANL C,/OV;进位标志CY设置为1 5. 逻辑或指令 1) ORL C, bit 该指令把进位标志CY的内容和比特位内容做逻辑或操作,结果保存在CY中,如表5.86所示。 表5.86ORL C,bit指令的内容 助记符操作标志操作码字节数周期数 ORL C,bit(PC)← (PC) + 2 (CY) ← (CY) ∨ (bit)CY0111001022 注意: 在操作码后面跟着1字节的位地址。 2) ORL C, /bit 该指令把进位标志CY的内容和比特位内容取反后做逻辑或操作,结果保存在CY中,如表5.87所示。 表5.87ORL C,/bit指令的内容 助记符操作标志操作码字节数周期数 ORL C,/bit(PC)← (PC) + 2 (CY) ← (CY) ∨ (bit)CY1010000022 注意: 在操作码后面跟着1字节的位地址。 【例533】假设P1端口的第0位为1,或者累加器A的第7位为1,或者溢出标志OV的内容为0,执行指令: MOV C,P1.0;进位标志CY设置为1 ORL C,ACC.7;进位标志CY设置为1 ORL C,/OV;进位标志CY设置为1 6. 传输指令 1) MOV C, bit 该指令把一个比特位的值复制到进位标志CY中,且比特位的值不发生变化,如表5.88所示。 表5.88MOV C,bit指令的内容 助记符操作标志操作码字节数周期数 MOV C,bit(PC)← (PC) + 2 (CY) ← (bit)CY1010001022 注意: 在操作码后面跟着1字节的位地址。 2) MOV bit,C 该指令把进位标志CY的内容复制到一个比特位中,且进位标志CY的值不发生变化,如表5.89所示。 表5.89MOV bit,C指令的内容 助记符操作标志操作码字节数周期数 MOV bit,C(PC)← (PC) + 2 (bit)← (C)N1001001023 注意: 在操作码后面跟着1字节的位地址。 【例534】假设进位标志CY的初值为1,端口P2中的数据为C5H(11000101B),端口P1中的数据为35H(00110101B),执行指令: MOV P1.3,C;P1端口的值变为3DH(00111101B) MOV C,P2.3;进位标志CY设置为0 MOV P1.2,C;P1端口的值变为39H(00111001B) 7. 跳转指令 1) JB bit,rel 该指令判断bit位中的数据是否为1,如果为1,则跳转到(PC) + rel指定的目标地址; 否则,程序转向下一条指令,该操作不影响标志位,如表5.90所示。 表5.90JB bit,rel指令的内容 助记符操作标志操作码字节数周期数 JB bit,rel(PC)← (PC) + 3 如果(bit) = 1,则(PC) ← (PC) + relN0010000035 注意: 在使用助记符编写汇编语言程序时,Keil μVision将助记符中的rel转换成程序存储空间内的一个目标地址。而在生成所对应的机器指令时,并不是直接使用rel所表示的目标地址,而是将其转换成一个相对偏移量rel.address,对于该条指令而言,相对偏移量的计算方法表示为 rel.address=rel(助记符所表示的目标地址)-PC-3 其中,rel.address对应于操作中(PC)+rel中的rel。 因此,读者一定要正确理解助记符中rel的含义,以及操作中rel所表示的含义。对于本条机器指令而言,操作码后面跟着1字节的位地址和1字节的偏移量rel.address,即表示为下面的形式 00100000bit addressrel.address 【例535】假设端口1的数据为CAH(11001010B),累加器A的内容为56H(01010110B)。则执行指令: JB P1.2,LABEL1;跳转条件不成立 JB ACC.2,LABEL2;跳转条件成立 结果: 程序跳转到标号LABEL2的地方执行。 2) JNB bit, rel 该指令判断bit中的数据是否为0,如果为0,则程序跳转到(PC) + rel指定的目标地址; 否则,程序转向下一条指令,该操作不影响标志位,如表5.91所示。 表5.91JNB bit,rel指令的内容 助记符操作标志操作码字节数周期数 JNB bit, rel(PC)← (PC) + 3 如果(bit) = 0,则(PC) ← (PC) + relN0011000035 注意: 在操作码后面跟着1字节的位地址和1字节的偏移量rel。 【例536】假设端口1的数据为CAH(11001010B),累加器A的内容为56H(01010110B)。则执行指令: JNB P1.3,LABEL1;跳转条件不成立 JNB ACC.3,LABEL2;跳转条件成立 结果: 程序跳转到标号LABEL2的地方执行。 3) JC rel 该指令判断进位标志位CY是否为1,如果为1,则跳转到(PC)+rel指定的目标地址; 否则,程序转向下一条指令,该操作不影响标志位,如表5.92所示。 表5.92JC rel指令的内容 助记符操作标志操作码字节数周期数 JC rel(PC)← (PC) + 2 如果(CY) = 1,则(PC) ← (PC) + relN0100000023 注意: 在操作码后面跟着1字节的偏移量rel。 【例537】假设进位标志CY为0,则执行指令: JC LABEL1; 跳转条件不成立 CPL C;取反,进位标志CY变为1 JC LABEL2;跳转条件成立 结果: 程序跳转到标号LABEL2的地方执行。 4) JNC rel 该指令判断进位标志位CY是否为0,如果为0,则跳转到(PC)+rel指定的目标地址; 否则,程序转向下一条指令,该操作不影响标志位,如表5.93所示。 表5.93JNC rel指令的内容 助记符操作标志操作码字节数周期数 JNC rel(PC)← (PC) + 2 如果(CY) = 0,则(PC) ← (PC) + relN0101000023 注意: 在操作码后面跟着1字节的偏移量rel。 【例538】假设进位标志CY为1,则执行指令: JNC LABEL1;跳转条件不成立 CPL C;取反,进位标志CY变为0 JNC LABEL2;跳转条件成立 结果: 程序跳转到标号LABEL2的地方执行。 5) JBC bit,rel 该指令判断指定bit位是否为1,如果为1,则将该位清零,并且跳转到(PC) + rel指定的目标地址; 否则,程序转向下一条指令,该操作不影响标志位,如表5.94所示。 表5.94JBC bit,rel指令的内容 助记符操作标志操作码字节数周期数 JBC bit, rel(PC)← (PC) + 3 如果(bit) = 1,则: bit← 0,(PC) ← (PC) + relN0001000035 注意: 在操作码后面跟着1字节的位地址和1字节的偏移量rel。 【例539】假设累加器A的内容为56H(01010110B),则执行指令: JBC ACC.3,LABEL1;跳转条件不成立 JBC ACC.2,LABEL2;跳转条件成立,并且将ACC.2清零 结果: 程序跳转到标号LABEL2的地方执行,累加器A的内容变为52H(01010010B)。 视频讲解 5.2.5程序分支指令 8051支持有条件和无条件的程序分支指令,这些程序分支指令用于修改程序的执行顺序。 1. 调用指令 1) ACALL addr11 该指令无条件地调用在指定地址处的子程序。目标地址由递增PC的高5位、操作码的第7~5位和指令第2字节并置组成。所以,所调用的子程序的首地址必须与ACALL后面指令的第1字节在同一个2KB区域内,如表5.95所示。 表5.95ACALL addr11指令的内容 助记符操作标志操作码字节数周期数 ACALL addr11(PC) ← (PC) + 2 (SP) ← (SP) + 1 ((SP)) ← (PC70) (SP) ← (SP) + 1 ((SP)) ← (PC158) (PC100) ←页面地址无a10a9a81001024 注意: a10a9a8是11位目标地址的A10~A8位。在操作码后面带着1字节目标地址的A7~A0位。 【例540】假设堆栈指针的初值为07H,标号SUBRTN位于程序存储器地址为0345H的位置,如果执行位于地址0123H处的指令: ACALL SUBRTN 结果: 堆栈指针的内容变成09H,内部RAM地址为08H和09H的位置保存的内容为25H和01H,PC值变为0345H。 2) LCALL addr16 该指令无条件地调用首地址为addr16处的子程序。执行该指令时,将PC加3,以获得下一条指令的地址。然后将指令第2、第3字节所提供的16位目标地址加载到PC150,程序转向子程序的首地址执行,如表5.96所示。所调用的子程序首地址可以在64KB的范围内。 表5.96LCALL addr16指令的内容 助记符操作标志操作码字节数周期数 LCALL addr16(PC)← (PC) + 3 (SP)← (SP) + 1 ((SP))← (PC70) (SP)← (SP) + 1 ((SP))← (PC158) (PC)← addr150N0001001034 注意: 在操作码后面带着1字节目标地址的A15~A8位和1字节目标地址的A7~A0位。 【例541】假设堆栈指针的初值为07H,标号SUBRTN位于程序存储器地址为1234H的位置,如果执行位于地址0123H处的指令: LCALL SUBRTN 结果: 堆栈指针的内容变成09H,内部RAM地址为08H和09H的位置保存的内容为26H和01H,PC值变为1234H。 2. 返回指令 1) RET 该指令将栈顶高地址和低地址字节连续地送给PC的高字节和低字节,并把堆栈指针减2,返回ACALL或LCALL的下一条指令,继续往下执行,该指令的操作不影响标志位,如表5.97所示。 表5.97RET指令的内容 助记符操作标志操作码字节数周期数 RET(PC158) ← ((SP)) (SP)← (SP) - 1 (PC70) ← ((SP)) (SP)← (SP) - 1N0010001014 【例542】堆栈指针的内容为0BH,内部RAM地址为0AH和0BH的位置保存的内容为23H和01H,如果执行指令: RET 结果: 堆栈指针的内容变成09H,程序将从地址为0123H的地方继续执行。 2) RETI 该指令将从中断服务程序返回,并清除相应的内部中断状态寄存器。CPU在执行RETI后,至少要再执行一条指令,才能响应新的中断请求,如表5.98所示。 表5.98RETI指令的内容 助记符操作标志操作码字节数周期数 RETI(PC158) ← ((SP)) (SP) ← (SP)- 1 (PC70) ← ((SP)) (SP) ← (SP)- 1N0011001014 【例543】堆栈指针的内容为0BH,在地址0123H处的指令执行结束期间产生中断,内部RAM地址为0AH和0BH的位置保存的内容为23H和01H,如果执行指令: RETI 结果: 堆栈指针的内容变成09H,中断返回后继续从程序代码地址为0123H的位置执行。 3. 无条件转移指令 1) AJMP addr11 该指令实现无条件跳转。绝对跳转操作的目标地址是由PC递增两次后值的高5位、操作码的第7~5位和第2字节并置而成,如表5.99所示。目标地址必须包含AJMP指令后第一条指令的第1字节在内的2KB范围内。 表5.99AJMP addr11指令的内容 助记符操作标志操作码字节数周期数 AJMP addr11(PC)← (PC) + 2 (PC100) ←页面地址Na10a9a80000123 注意: a10a9a8是11位目标地址的A10~A8位。在操作码后面带着1字节目标地址的A7~A0位。 【例544】假设标号JMPADR位于程序存储器的0123H的位置,如果指令: AJMP JMPADR 位于程序存储器地址为0345H的位置。 结果: 执行完该指令后,PC的值变为0123H。 2) LJMP addr16 该指令实现无条件长跳转操作,跳转的16位目的地址由指令的第2和第3字节组成,如表5.100所示。因此,程序指向的目标地址可以包含程序存储器的整个64KB空间。 表5.100LJMP addr16指令的内容 助记符操作标志操作码字节数周期数 LJMP addr16(PC)← addr15…addr0N0000001034 注意: 在操作码后面带着1字节目标地址的A15~A8位和1字节目标地址的A7~A0位。 【例545】假设标号JMPADR位于程序存储器的1234H的位置,如果指令: LJMP JMPADR 位于程序存储器地址为1234H的位置。 结果: 执行完该指令后,PC的值变为1234H。 3) SJMP rel 该指令实现无条件短跳转操作,跳转的目的地址是由PC递增两次后的值和指令的第2字节带符号的相对地址相加而成的,如表5.101所示。 表5.101SJMP rel指令的内容 助记符操作标志操作码字节数周期数 SJMP rel(PC)← (PC) + 2 (PC)← (PC) + relN1000000023 注意: 在操作码后面带着1字节的相对偏移量rel。 【例546】假设标号RELADR位于程序存储器的0123H的位置,如果指令: SJMP RELADR 位于程序存储器地址为0100H的位置。 结果: 执行完该指令后,PC的值变为0123H。 注: 在上面这个例子中,紧接SJMP的下一条指令的地址是0102H,因此跳转的偏移量为0123H-0102H=21H。 4) JMP @A+DPTR 该指令实现无条件的跳转操作,跳转的目标地址是将累加器A中的8位无符号数与数据指针DPTR的内容相加而得。相加运算不影响累加器A和数据指针DPTR的原内容,如表5.102所示。若相加结果大于64KB,则从程序存储器的零地址往下延续。 表5.102JMP @A+DPTR指令的内容 助记符操作标志操作码字节数周期数 JMP @A+DPTR(PC)← (A) + (DPTR)N0111001115 【例547】假设累加器A中的值是偶数(0~6)。下面的指令序列将使程序跳转到位于跳转表JMP_TBL的4条AJMP指令中的某一条去执行: MOV DPTR,#JMP_TBL JMP @A+DPTR JMP_TBL: AJMP LABEL0 AJMP LABEL1 AJMP LABEL2 AJMP LABEL3 如果开始执行上面指令时,累加器A中的值为04H,那么程序最终会跳到标号为LABEL2的地方执行。 注意: AJMP是一个2字节指令,所以在跳转表中,各个跳转指令的入口地址依次相差2字节。 4. 有条件转移指令 1) JNZ rel 该指令实现有条件跳转。判断累加器A的内容是否不为0,如果不为0,则跳转到(PC) + rel指定的目标地址; 否则,程序转向下一条指令,如表5.103所示。 表5.103JNZ rel指令的内容 助记符操作标志操作码字节数周期数 JNZ rel(PC)← (PC) + 2 如果(A) ≠ 0,则(PC) ← (PC) + relN0111000024 注意: 在操作码后面带着1字节的偏移量rel。 【例548】假设累加器A的内容为00H,则执行指令: JNZ LABEL1; 跳转条件不成立 INC A;累加器的内容加1 JNZ LABEL2;跳转条件成立 结果: 程序跳转到标号LABEL2的地方执行。 2) JZ rel 该指令实现有条件跳转。判断累加器A的内容是否为0,如果为0,则跳转到(PC) + rel指定的目标地址; 否则,程序转向下一条指令,如表5.104所示。 表5.104JZ rel指令的内容 助记符操作标志操作码字节数周期数 JZ rel(PC)← (PC) + 2 如果(A) = 0,则(PC) ← (PC) + relN0110000024 注意: 在操作码后面带着1字节的偏移量rel。 【例549】假设累加器A的内容为01H,则执行指令: JZ LABEL1; 跳转条件不成立 DEC A;累加器的内容减1 JZ LABEL2;跳转条件成立 结果: 程序跳转到标号LABEL2的地方执行。 3) CJNE A, direct, rel 该指令对累加器A和直接寻址单元内容相比较,若它们的值不相等,则程序转移到(PC) + rel指向的目标地址。若直接寻址单元的内容小于累加器内容,则清除进位标志CY; 否则,置位进位标志CY,如表5.105所示。 表5.105CJNE A, direct, rel指令的内容 助记符操作标志操作码字节数周期数 CJNE A,direct,rel(PC)← (PC) + 3 如果(A) ≠ (direct),则 (PC)← (PC) + rel 如果(A) < (direct),则(CY) ← 1 否则(CY) ← 0CY1011010135 注意: 在操作码后面跟着1字节的直接地址和1字节的偏移量rel。 4) CJNE A, #data, rel 该指令将比较累加器A的内容和立即数,若它们的值不相等,则程序转移(PC) + rel指向的目标地址。进位标志CY设置同上,该指令不影响累加器A的内容,如表5.106所示。 表5.106CJNE A, #data, rel指令的内容 助记符操作标志操作码字节数周期数 CJNE A,#data,rel(PC)← (PC) + 3 如果(A) ≠ data,则 (PC)← (PC) + rel 如果(A) < data,则 (CY) ← 1 否则(CY) ← 0CY1011010134 注意: 在操作码后面跟着1字节的立即数和1字节的偏移量rel。 5) CJNE Rn, #data, rel 该指令将寄存器Rn的内容和立即数进行比较,若它们的值不相等,则程序转移到(PC) + rel指向的目标地址。进位标志CY设置同上,如表5.107所示。 表5.107CJNE Rn, #data, rel指令的内容 助记符操作标志操作码字节数周期数 CJNE Rn,#data,rel(PC)← (PC) + 3 如果(Rn) ≠ data,则 (PC)← (PC) + rel 如果(Rn) 60H 结果: 第一条指令将进位标志CY设置为1,程序跳转到标号NOT_EQ的地方。接着测试进位标志CY,可以确定寄存器R7的内容大于还是小于60H。 7) DJNZ Rn,rel 该指令实现有条件跳转。每执行一次指令,寄存器Rn的内容减1,并判断其内容是否为0。若不为0,则转向(PC) + rel指向的目标地址,继续执行循环程序,否则,结束循环程序,执行下一条指令,如表5.109所示。 表5.109DJNZ Rn,rel指令的内容 助记符操作标志操作码字节数周期数 DJNZ Rn, rel(PC)← (PC) + 2 (Rn)← (Rn) - 1 如果(Rn) ≠ 0,则 (PC)← (PC) + relN11011rrr24 注意: rrr为寄存器的编号,因此机器码范围是D8H~DFH。在操作码后面跟着1字节的偏移量rel。 8) DJNZ direct,rel 该指令实现有条件跳转。每执行一次指令,直接寻址单元的内容减1,并判断其内容是否为0。若不为0,则转向(PC) + rel指向的目标地址,继续执行循环程序,否则,结束循环程序,执行下一条指令,如表5.110所示。 表5.110DJNZ direct,rel指令的内容 助记符操作标志操作码字节数周期数 DJNZ direct, rel(PC)← (PC) + 3 (direct)← (Rn) - 1 如果(direct) ≠ 0,则 (PC)← (PC) + relN1101010135 注意: 在操作码后面跟着1字节的直接地址和1字节的偏移量rel。 【例551】假设内部RAM地址为40H、50H和60H的单元分别保存着数据01H、70H和15H,则执行指令: DJNZ 40H,LABEL_1 DJNZ 50H,LABEL_2 DJNZ 60H,LABEL_3 结果: 程序将跳转到标号LABEL_2处执行,且相应的3个RAM单元的内容变成00H、6FH和15H。 5. 空操作指令 NOP指令表示无操作,如表5.111所示。 表5.111NOP指令的内容 助记符操作标志操作码字节数周期数 NOP(PC)← (PC) + 1N0x0011 【例552】假设期望在端口P2的第7位引脚上输出一个长时间的低电平脉冲,该脉冲持续5个机器周期(精确)。若仅仅使用SETB和CLR指令序列,生成的脉冲只能持续一个机器周期。因此,需要设法增加4个额外的机器周期,可以按照下面的方式实现所要求的功能(假设在此期间没有使能中断): CLR P2.7 NOP NOP NOP NOP SETB P2.7