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指令集分为算术指令、逻辑指令、数据传送指令、布尔指令、程序分支指令。
算术指令支持直接、间接、寄存器、立即数和寄存器指定指令寻址方式。算术模式用于加、减、乘、除、递增和递减操作。
1)ADD A,Rn
该指令将寄存器Rn的内容和累加器A的内容相加,结果保存在累加器A中,如表6.1所示。并设置CY标志、AC标志,以及溢出标志OV。
表6.1 ADD A,Rn指令的内容
(1)当和的第3位和第7位有进位时,分别将AC、CY标志置位,否则置0。
(2)对于带符号运算数,当和的第7位与第6位中有一位进位,而另一位不产生进位时,溢出标志OV置位,否则清0。或者可以这样说,当两个正数相加时,相加的结果为负数;或当两个负数相加时,相加的结果为正数时,在这两种情况下设置OV为1。
注意: rrr为寄存器的编号,因此机器码范围是28H~2FH。
【例6-1】 假设累加器A中的数据为C3H,R0寄存器中的数据为AAH。执行指令:
ADD A,R0
结果:
(A)=6DH,(AC)=0,(CY)=1,(OV)=1
注意: ()表示内容。
计算过程为
2)ADD A,direct
该指令将直接寻址单元的内容和累加器A的内容相加,结果保存在累加器A中,如表6.2所示。CY、AC、OV标志的设置同上。
表6.2 ADD A,direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
3)ADD A,@Ri
该指令将间接寻址单元的内容和累加器A的内容相加,结果保存在累加器A中,如表6.3所示。CY、AC、OV标志的设置同上。
表6.3 ADD A,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
4)ADD A,#data
该指令将一个立即数和累加器A的内容相加,结果保存在累加器A中,如表6.4所示。CY、AC、OV标志的设置同上。
表6.4 ADD A,#data指令的内容
注意: 在操作码后面跟着一字节的立即数。
5)ADDC A,Rn
该指令将寄存器Rn的内容与累加器A的内容及进位标志CY的内容相加,结果保存在累加器A中,如表6.5所示。CY、AC、OV标志的设置同上。
表6.5 ADDC A,Rn指令的内容
注意: rrr为寄存器的编号,因此机器码范围是38H~3FH。
【例6-2】 假设累加器A中的数据为C3H,R0寄存器中的数据为AAH,进位标志为1时,执行指令:
ADDC A,R0
结果:
(A)=6EH,(AC)=0,(CY)=1,(OV)=1
注意: 计算过程为
6)ADDC A,direct
该指令将直接寻址单元的内容与累加器A的内容及进位标志CY中的内容相加,结果保存在累加器A中,如表6.6所示。CY、AC、OV标志的设置同上。
表6.6 ADDC A,direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
7)ADDC A,@Ri
该指令将间接寻址单元的内容与累加器A的内容及进位标志CY中的内容相加,结果保存在累加器A中,如表6.7所示。CY、AC、OV标志的设置同上。
表6.7 ADDC A,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
8)ADDC A,#data
该指令将一个立即数与累加器A的内容及进位标志CY中的内容相加,结果保存在累加器A中,如表6.8所示。CY、AC、OV标志的设置同上。
表6.8 ADDC A,#data指令的内容
注意: 在操作码后面跟着一字节的立即数。
1)SUBB A,Rn
该指令从累加器A中减去寄存器Rn和进位标志CY内的内容,将结果保存在累加器A中,如表6.9所示。
表6.9 SUBB A,Rn指令的内容
(1)如果第7位需要一个借位,则设置进位(借位)标志;否则,清除CY标志。
注意: 如果在执行指令前,已经设置了CY标志,则表示前面的多个步骤需要一个借位。这样,从累加器中减去进位标志以及源操作数。
(2)如果第3位需要一个借位,则设置AC标志;否则,清除AC标志。
(3)如果第6位需要借位,而第7位没有借位;或者第7位有借位,而第6位没有借位,在这两种情况下都会设置OV标志。或者可以这样说,当减去有符号的整数时,当一个正数减去一个负数,产生一个负数结果时;或者一个负数减去一个正数时,产生一个正数结果时,设置OV标志。
注意: rrr为寄存器的编号,因此机器码范围是98H~9FH。
【例6-3】 假设累加器A中的数据为C9H,R2寄存器中的数据为54H,进位标志为1时,执行指令:
SUBB A,R2
结果:
(A)=74H,(AC)=0,(CY)=0,(OV)=1。
注意: 计算过程为
2)SUBB A,direct
该指令从累加器A中减去直接寻址单元的内容和进位标志CY的内容,然后结果保存在累加器A中,如表6.10所示。CY、AC、OV标志的设置同上。
表6.10 SUBB A,direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
3)SUBB A,@Ri
该指令从累加器A中减去间接寻址单元的内容和进位标志CY的内容,然后结果保存在累加器A中,如表6.11所示。CY、AC、OV标志的设置同上。
表6.11 SUBB A,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
4)SUBB A,#data
该指令从累加器A中减去一个立即数和进位标志CY的内容,然后结果保存在累加器A中,如表6.12所示。CY、AC、OV标志的设置同上。
表6.12 SUBB A,#data指令的内容
注意: 操作码后面跟着一字节的立即数。
1)INC A
该指令将累加器A的内容加1,结果保存在累加器A中,如表6.13所示。若累加器A的结果为0xFF,在执行完该指令后,将其内容设置为0。
表6.13 INC A指令的内容
2)INC Rn
该指令将寄存器Rn的内容加1,结果保存在Rn中,如表6.14所示。若Rn的结果为0xFF,在执行完该指令后,将其内容设置为0。
表6.14 INC Rn指令的内容
注意: rrr为寄存器的编号,因此机器码是08H~0FH。
3)INC direct
该指令将直接寻址单元的内容加1,结果保存在直接地址单元中,如表6.15所示。若直接地址单元的结果为0xFF,在执行完该指令后,将其内容设置为0。
表6.15 INC direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
4)INC@Ri
该指令将间接寻址单元的内容加1,结果保存在间接地址单元中,如表6.16所示。若间接地址单元的结果为0xFF,则将其内容设置为0。
表6.16 INC@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
5)INC DPTR
该指令将DPTR的内容加1,结果保存在DPTR中,如表6.17所示。若DPTR的结果为0xFFFF,在执行完该指令后,将其内容设置为0x0000。
表6.17 INC DPTR指令的内容
【例6-4】 假设寄存器R0中的数据为7EH,内部RAM地址为7EH和7FH单元的数据分别为FFH和40H,即(7E)=FFH,(7F)=40H,则当执行指令:
INC @R0 ;内部RA M地址为7EH单元的内容加1,变成00H INC R0 ;寄存器R0中的数据变为7FH INC @R0 ;内部RA M地址为7FH单元的内容加1,变成41H
结果:
(R0)=7FH,内部RAM地址为7EH和7FH单元的数据变为00H和41H。
1)DEC A
该指令将累加器A的内容减1,结果保存在累加器A中,如表6.18所示。如果累加器A中的内容为0,在执行完该指令后,变为0xFF。
表6.18 DEC A指令的内容
2)DEC Rn
该指令将寄存器Rn的内容减1,结果保存在寄存器Rn中,如表6.19所示。如果Rn的内容为0,在执行完该指令后,变为0xFF。
表6.19 DEC Rn指令的内容
注意: rrr为寄存器的编号,因此机器码范围是18H~1FH。
3)DEC direct
该指令将直接寻址单元的内容减1,结果保存在直接地址单元中,如表6.20所示。如果直接寻址单元的内容为0,在执行完该指令后,变为0xFF。
表6.20 DEC direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
4)DEC@Ri
该指令将间接寻址单元的内容减1,结果保存在间接地址单元中,如表6.21所示。如果间接寻址单元的内容为0,在执行完该指令后,变为0xFF。
表6.21 DEC@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
【例6-5】 假设寄存器R0中的数据为7FH,内部RAM地址为7EH和7FH单元的数据分别为40H和00H,即(7F)=00H,(7E)=40H,则当执行指令:
结果:
(R0)=7EH,内部RAM地址为7EH和7FH单元的数据变为FFH和3FH。
MUL AB指令将累加器A和寄存器B中的两个无符号8位二进制数相乘,所得的16位乘积的低8位结果保存在累加器A中,高8位结果保存在寄存器B中,如表6.22所示。
如果乘积大于255,则溢出标志OV置1;否则OV清零。在执行该指令时,总是清除进位标志CY。
表6.22 MUL AB指令的内容
【例6-6】 假设累加器A中的数据为(80) 10 =50H,寄存器B中的数据为(160) 10 =A0H,则执行指令:
MUL AB
结果:乘积为(12800) 10 =3200H,(A)=00H,(B)=32H,(CY)=0,(OV)=1。
注意: 计算过程为
DIV AB指令用累加器A中的无符号整数除以寄存器B中无符号整数,所得的商保存在累加器A中,余数保存在寄存器B中,如表6.23所示。当除数(B寄存器的内容)为0时,结果不定,溢出标志OV置1。在执行该指令时,清除进位标志CY。
表6.23 DIV AB指令的内容
【例6-7】 假设累加器A中的数据为(251) 10 =FBH,寄存器B中的数据为(18) 10 =12H,则执行指令:
DIV AB
结果:(A)=0DH,(B)=11H,(CY)=0,(OV)=0。
注意: 计算过程为
DA A指令的功能是对BCD码的加法结果进行调整。两个压缩型BCD码按十进制数相加后,需经此指令的调整才能得到压缩型BCD码的和数,如表6.24所示。
表6.24 DA A指令的内容
本指令是根据A的最初数值和程序状态字PSW的状态,决定对A进行加06H、60H或66H操作的。
注意: 如果前面没有使用加法运算,则不能直接使用DA指令。此外,如果前面执行的是减法运算,则DA指令也不起任何作用。
【例6-8】 假设累加器A中的数据为56H,表示十进制数56的BCD码。寄存器R3的内容为67H,表示十进制数67的BCD码。进位标志为1,则执行指令:
结果表示为(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,最高位有进位。
思考与练习6-5: 假定(A)=66H,(R0)=55H,(55H)=FFH,执行指令:
ADD A,@R0
(A)= ,(CY)= ,(OV)= 。
思考与练习6-6: 如果(A)=60H,(B)=73H,(CY)=1时,执行指令:
ADDC A,B
(A)= ,(CY)= ,(OV)= 。
思考与练习6-7: 如果(A)=3DH,(B)=4EH,执行指令:
MUL AB
(A)= ,(B)= 。
逻辑指令执行布尔操作,如逻辑与、逻辑或、逻辑异或操作,对累加器内容进行旋转,累加器半字交换。
1)ANL A,Rn
该指令将累加器A的内容和寄存器Rn的内容做逻辑与操作,结果保存在累加器A中,如表6.25所示。
表6.25 ANL A,Rn指令的内容
注意: rrr为寄存器的编号,因此机器码范围是58H~5FH。
【例6-9】 假设累加器A中的数据为C3H,寄存器R0的内容为55H,则执行指令:
ANL A,R0
结果:
累加器A中的数据为41H。
注意: 计算过程为
【例6-10】 执行指令
ANL P1,#01110011B
结果:
将端口1的第7位、第3位和第2位清零。
2)ANL A,direct
该指令将累加器A的内容和直接寻址单元的内容做逻辑与操作,结果保存在累加器A中,如表6.26所示。
表6.26 ANL A,direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
3)ANL A,@Ri
该指令将累加器A的内容和间接寻址单元中的内容做逻辑与操作,结果保存在累加器A中,如表6.27所示。
表6.27 ANL A,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
4)ANL A,#data
该指令将累加器A的内容和立即数做逻辑与操作,结果保存在累加器A中,如表6.28所示。
表6.28 ANL A,#data指令的内容
注意: 在操作码后面跟着一字节的立即数。
5)ANL direct,A
该指令将累加器A的内容和直接寻址单元的内容做逻辑与操作,结果保存在直接寻址单元中,如表6.29所示。
表6.29 ANL direct,A指令的内容
注意: 在操作码后面跟着一字节的直接地址。
6)ANL direct,#data
该指令对立即数和直接寻址单元的内容做逻辑与操作,结果保存在直接寻址单元中,如表6.30所示。
表6.30 ANL direct,#data指令的内容
注意: 在操作码后面跟着一字节的直接地址和一字节的立即数。
1)ORL A,Rn
该指令将累加器A的内容和寄存器Rn中内容做逻辑或操作,结果保存在累加器A中,如表6.31所示。
表6.31 ORL A,Rn指令的内容
注意: rrr为寄存器的编号,因此机器码范围是48H~4FH。
【例6-11】 假设累加器A中的数据为C3H,寄存器R0的内容为55H,则执行指令:
ORL A,R0
结果:
累加器A中的数据为D7H。
注意: 计算过程为
【例6-12】 执行指令
ORL P1,#00110010B
结果:
将端口1的第5位、第4位和第1位置1。
2)ORL A,direct
该指令将累加器A的内容和直接寻址单元的内容做逻辑或操作,结果保存在累加器A中,如表6.32所示。
表6.32 ORL A,direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
3)ORL A,@Ri
该指令将累加器A的内容和间接寻址单元中内容做逻辑或操作,结果保存在累加器A中,如表6.33所示。
表6.33 ORL A,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
4)ORL A,#data
该指令将累加器A的内容和立即数做逻辑或操作,结果保存在累加器A中,如表6.34所示。
表6.34 ORL A,#data指令的内容
注意: 在操作码后面跟着一字节的立即数。
5)ORL direct,A
该指令将直接寻址单元的内容和累加器A的内容做逻辑或操作,结果保存在直接寻址单元中,如表6.35所示。
表6.35 ORL direct,A指令的内容
注意: 在操作码后面跟着一字节的直接地址。
6)ORL direct,#data
该指令将直接寻址单元中内容和立即数做逻辑或操作,结果保存在直接寻址单元中,如表6.36所示。
表6.36 ORL direct,#data指令的内容
注意: 在操作码后面跟着一字节的直接地址和一字节的立即数。
1)XRL A,Rn
该指令将累加器A的内容和寄存器Rn的内容做逻辑异或操作,结果保存在累加器A中,如表6.37所示。
表6.37 XRL A,Rn指令的内容
注意: rrr为寄存器的编号,因此机器码范围是68H~6FH。
【例6-13】 假设累加器A中的数据为C3H,寄存器R0的内容为AAH,则执行指令:
XRL A,R0
结果:
累加器A中的数据为69H。
注意: 计算过程为
【例6-14】 执行指令
XRL P1,#00110001B
结果:
将端口1的第5位、第4位和第0位取反。
2)XRL A,direct
该指令将累加器A的内容和直接寻址单元的内容做逻辑异或操作,结果保存在累加器A中,如表6.38所示。
表6.38 XRL A,direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
3)XRL A,@Ri
该指令将累加器A的内容和间接寻址单元的内容做逻辑异或操作,结果保存在累加器A中,如表6.39所示。
表6.39 XRL A,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
4)XRL A,#data
该指令将累加器A的内容和一个立即数做逻辑异或操作,结果保存在累加器A中,如表6.40所示。
表6.40 XRL A,#data指令的内容
注意: 在操作码后面跟着一字节的立即数。
5)XRL direct,A
该指令将直接寻址单元的内容和累加器A的内容做逻辑异或操作,结果保存在直接寻址的单元中,如表6.41所示。
表6.41 XRL direct,A指令的内容
注意: 在操作码后面跟着一字节的直接地址。
6)XRL direct,#data
该指令将直接寻址的内容和一个立即数做逻辑异或操作,结果保存在直接寻址的单元中,如表6.42所示。
表6.42 XRL direct,#data指令的内容
注意: 在操作码后面跟着一字节的直接地址和一字节的立即数。
CLR A指令将累加器A中的各位清0,如表6.43所示。
表6.43 CLR A指令的内容
【例6-15】 假设累加器A中的数据为5CH,则执行指令:
CLR A
结果:
(A)=00H。
CPL A指令将累加器A按位取反,即将累加器A各位中的逻辑1变成逻辑0,逻辑0变成逻辑1,如表6.44所示。
表6.44 CPL A指令的内容
【例6-16】 假设P1端口的数据为5BH,则执行指令:
CPL P1.1 CPL P1.2
结果:
将P1端口设置为5DH=01011101B。
1)RL A
该指令将累加器A中的内容循环左移,如表6.45所示。
表6.45 RL A指令的内容
【例6-17】 假设累加器A的数据为C5H(11000101B),则执行指令:
RL A
结果:
累加器A的数据变成8BH=10001011B。
2)RLC A
该指令将累加器A的内容和进位标志CY一起循环左移,如表6.46所示。
表6.46 RLC A指令的内容
【例6-18】 假设累加器A的数据为C5H(11000101B),进位标志(CY)=0,则执行指令:
RLC A
结果:
累加器A的内容变成8AH=10001010B,进位标志(CY)=1。
3)RR A
该指令将累加器A的内容循环右移,如表6.47所示。
表6.47 RR A指令的内容
【例6-19】 假设累加器A的数据为C5H(11000101B),则执行指令:
RR A
结果:
累加器A的内容变成E2H=11100010B。
4)RRC A
该指令将累加器A的内容和进位标志CY一起循环右移,如表6.48所示。
表6.48 RRC A指令的内容
【例6-20】 假设累加器A的数据为C5H(11000101B),进位标志(CY)=0,则执行指令:
RRC A
结果:
累加器A的内容变成62H=01100010B,进位标志(CY)=1。
SWAP A指令将累加器A中的半字节互换,即将累加器A的高、低半字节互换,如表6.49所示。
表6.49 SWAP A指令的内容
【例6-21】 假设累加器A的数据为C5H(11000101B),则执行指令:
SWAP A
结果:
累加器A的内容变成5CH=01011100B。
思考与练习6-8: 如果(A)=AAH,(R0)=55H,则
(1)执行指令
ANL A,R0
(A)= 。
(2)执行指令
ORL A,R0
(A)= 。
(3)执行指令
XRL A,R0
(A)= 。
(4)执行指令
RL A
(A)= 。
STC单片机中的数据传送指令包括数据传输指令、堆栈操作指令和数据交换指令。
STC单片机中的数据传输指令包括内部数据传输指令、外部数据传输指令和查找表传输指令。
1)内部数据传输指令
该类型数据传输指令是在任何两个内部RAM或者SFR间实现数据传输。这些指令使用直接、间接、寄存器和立即数寻址。
(1)MOV A,Rn
该指令将寄存器Rn中的内容复制到累加器A中,且Rn的内容不发生变化,如表6.50所示。
表6.50 MOV A,Rn指令的内容
注意: rrr为寄存器的编号,因此机器码范围是E8H~EFH。
(2)MOV A,direct
该指令将直接寻址单元的内容复制到累加器A中,且直接寻址单元的内容不发生变化,如表6.51所示。
表6.51 MOV A,direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
(3)MOV A,@Ri
该指令将间接寻址单元中的内容复制到累加器A中,且间接寻址单元的内容不发生变化,如表6.52所示。
表6.52 MOV A,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
(4)MOV A,#data
该指令将立即数复制到累加器A中,且立即数的内容不发生变化,如表6.53所示。
表6.53 MOV A,#data指令的内容
注意: 在操作码后面跟着一字节的立即数。
(5)MOV Rn,A
该指令将累加器A的内容复制到寄存器Rn中,且累加器A的内容不发生变化,如表6.54所示。
表6.54 MOV Rn,A指令的内容
注意: rrr为寄存器的编号,因此机器码范围是F8H~FFH。
(6)MOV Rn,direct
该指令将直接寻址单元的内容复制到寄存器Rn中,且直接寻址单元的内容不发生变化,如表6.55所示。
表6.55 MOV Rn,direct指令的内容
注意: rrr为寄存器的编号,因此机器码范围是A8H~AFH;在操作码后面跟着一字节的直接地址。
(7)MOV Rn,#data
该指令将立即数复制到寄存器Rn中,且立即数的内容不发生变化,如表6.56所示。
表6.56 MOV Rn,#data指令的内容
注意: rrr为寄存器的编号,因此机器码范围是78H~7FH;在操作码后面跟着一字节的立即数。
(8)MOV direct,A
该指令将累加器A的内容复制到直接寻址单元中,且累加器A的内容不发生变化,如表6.57所示。
表6.57 MOV direct,A指令的内容
注意: 在操作码后面跟着一字节的直接地址。
(9)MOV direct,Rn
该指令将寄存器Rn的内容复制到直接寻址单元中,且Rn的内容不发生变化,如表6.58所示。
表6.58 MOV direct,Rn指令的内容
注意: rrr为寄存器的编号,因此机器码范围是88H~8FH;在操作码后面跟着一字节的直接地址。
(10)MOV direct,direct
该指令将直接寻址单元的内容复制到另一个直接寻址单元中,且源直接寻址单元的内容不发生变化,如表6.59所示。
表6.59 MOV direct,direct指令的内容
注意: 在操作码后面跟着两字节的直接地址,一个是源操作数地址,另一个是目的操作数地址。
(11)MOV direct,@Ri
该指令将间接寻址单元的内容复制到直接寻址单元中,且间接寻址单元的内容不发生变化,如表6.60所示。
表6.60 MOV direct,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。在操作码后面跟着一字节的直接地址。
(12)MOV direct,#data
该指令将立即数复制到直接寻址单元中,且立即数的内容不发生变化,如表6.61所示。
表6.61 MOV direct,#data指令的内容
注意: 在操作码后面跟着一字节的直接地址和一字节的立即数。
(13)MOV@Ri,A
该指令将累加器A的内容复制到间接寻址的单元中,且累加器A的内容不发生变化,如表6.62所示。
表6.62 MOV@Ri,A指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
(14)MOV@Ri,direct
该指令将直接寻址单元的内容复制到间接寻址的寄存器中,且直接寻址寄存器内容不发生变化,如表6.63所示。
表6.63 MOV@Ri,direct指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。在操作码后面跟着一字节的直接地址。
(15)MOV@Ri,#data
该指令将立即数内容复制到间接寻址单元中,且立即数的内容不发生变化,如表6.64所示。
表6.64 MOV@Ri,#data指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。在操作码后面跟着一字节的立即数。
(16)MOV DPTR,#data16
该指令将一个16位的立即数复制到数据指针寄存器DPTR中,且16位立即数的内容不发生变化,如表6.65所示。
表6.65 MOV DPTR,#data16指令的内容
注意: 在操作码后面跟着两字节(16位)的立即数。
【例6-22】 假设内部RAM地址为30H的单元的内容为40H,而40H单元的内容为10H。端口1的数据为CAH(11001010B),则执行指令:
2)外部数据传输指令
该类型传输指令是在累加器和8051片内扩展RAM和外部扩展RAM地址空间实现数据传输,这种传输只能使用MOVX指令。
(1)MOVX A,@Ri
该指令将外部数据存储区的一字节的内容复制到累加器A中。8位外部数据存储区地址由R0或R1确定,且外部数据存储器单元的内容不发生变化,如表6.66所示。
表6.66 MOVX A,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
【例6-23】 假设有一个时分复用地址/数据线的外部RAM存储器,容量为256B,该存储器连接到STC单片机的P0端口上,端口P3用于提供外部RAM所需要的控制信号。端口P1和P2用作通用输入/输出端口。R0寄存器和R1寄存器中的数据分别为12H和34H,外部RAM地址为34H的单元内容为56H,执行指令:
(2)MOVX A,@DPTR
该指令将外部数据存储区的一字节的内容复制到累加器A中。16位外部数据存储区单元的地址由DPTR寄存器确定,且外部数据存储器单元的内容不发生变化,如表6.67所示。
表6.67 MOVX A,@DPTR指令的内容
(3)MOVX@Ri,A
该指令将累加器A的内容复制到外部数据存储单元中。8位外部数据存储区地址由R0或R1确定,且累加器A中的内容不发生变化,如表6.68所示。
表6.68 MOVX@Ri,A指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
(4)MOVX@DPTR,A
该指令将累加器A的内容复制到外部数据存储单元中。16位外部数据存储区单元的地址由DPTR寄存器确定,且累加器A中的内容不发生变化,如表6.69所示。
表6.69 MOVX@DPTR,A指令的内容
3)查找表传输指令
只在累加器和程序存储器之间实现数据传输,这种传输只能使用MOVC指令。
(1)MOVC A,@A+DPTR
该指令将数据指针寄存器DPTR和累加器A的内容相加所得到的存储器地址单元的内容复制到累加器A中,如表6.70所示。
表6.70 MOVC A,@A+DPTR指令的内容
【例6-24】 假设累加器A的值在0~4,下面的子程序将累加器A中的值转换为用DB伪指令定义的4个值之一:
如果在调用该子程序之前累加器的值为02H,执行完该子程序后,累加器的值变为88H。MOVC指令之前的INC A指令是为了在查表时跨越RET而设置的。如果MOVC和表格之间被多字节隔开,则为了正确地读取表格,必须将相应的字节数预先加到累加器A上。
(2)MOVC A,@A+PC
该指令将程序计数器PC和累加器A的内容相加所得到的存储器地址单元的内容复制到累加器A中,如表6.71所示。
表6.71 MOVC A,@A+PC指令的内容
1)POP direct
该指令将堆栈指针SP所指向栈顶的内容保存到直接寻址单元中,然后执行(SP)-1→(SP)的操作,此操作不影响标志位,如表6.72所示。
表6.72 POP direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
【例6-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所指向的堆栈空间,此操作不影响标志位,如表6.73所示。
表6.73 PUSH direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
【例6-26】 假设在进入中断服务程序之前堆栈指针的值为09H,数据指针DPTR的值为0123H,则执行下面的指令:
PUSH DPL PUSH DPH
结果:
堆栈指针变成0BH,并把数据23H和01H分别保存到内部RAM的0AH和0BH的存储单元中。
1)XCH A,Rn
该指令将累加器A的内容和寄存器Rn中的内容互相交换,如表6.74所示。
表6.74 XCH A,Rn指令的内容
注意: rrr为寄存器的编号,因此机器码范围是C8H~CFH。
2)XCH A,direct
该指令将累加器A的内容和直接寻址单元的内容互相交换,如表6.75所示。
表6.75 XCH A,direct指令的内容
注意: 在操作码后面跟着一字节的直接地址。
3)XCH A,@Ri
该指令将累加器A的内容和间接寻址的内容互相交换,如表6.76所示。
表6.76 XCH A,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
【例6-27】 假设R0的内容为地址20H,累加器A的内容为3FH。内部RAM地址为20H单元的内容为75H,执行指令:
XCH A,@R0
结果:
执行该指令后,将20H所指向的内部RAM的单元的数据75H和累加器A的内容3FH进行交换,结果是累加器A的内容变成75H,而内部RAM地址为20H单元的内容变成3FH。
4)XCHD A,@Ri
该指令将累加器A的内容和间接寻址单元内容的低半字节互相交换,如表6.77所示。
表6.77 XCHD A,@Ri指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。
【例6-28】 假设寄存器R0的内容为20H,累加器A的内容为36H,内部RAM地址为20H的单元内容为75H,执行指令:
XCHD A,@R0
结果:
将20H所指向内部RAM单元的数据75H和累加器A的内容36H的低4位数据进行交换,结果是累加器A的内容变成35H,而内部RAM地址为20H单元的内容变成76H。
思考与练习6-9: 假设(30H)=40H,(31H)=5DH,(SP)=15H,则执行下面的指令:
PUSH 30H PUSH 31H
的目的是 ,(SP)= 。
8051单片机有独立的位可寻址区域。它有128比特的位可寻址的RAM和SFR。
1)CLR bit
该指令将目的比特位清0,如表6.78所示。
表6.78 CLR bit指令的内容
注意: 在操作码后面跟着一字节的位地址。
【例6-29】 假设端口P1的数据为5DH(01011101B),执行指令:
CLR P1.2
结果:
端口P1的内容为59H(01011001B)。
2)CLR C
该指令将进位标志位CY清0,如表6.79所示。
表6.79 CLR C指令的内容
1)SETB bit
该指令将目标比特位置1,如表6.80所示。
表6.80 SETB bit指令的内容
注意: 在操作码后面跟着一字节的位地址。
2)SETB C
该指令将进位标志CY置1,如表6.81所示。
表6.81 SETB C指令的内容
【例6-30】 假设端口P1的数据为34H(00110100B),执行指令:
SETB C SETB P1.0
结果:
进位标志(CY)=1,端口P1的数据变成为35H(00110101B)。
1)CPL bit
该指令将目标比特位取反,如表6.82所示。
表6.82 CPL bit指令的内容
注意: 在操作码后面跟着一字节的位地址。
【例6-31】 假设端口P1的数据为5BH(01011011B),执行指令:
CPL P1.1 CPL P1.2
结果:
端口P1的数据变成为5DH(01011101B)。
2)CPL C
该指令将进位标志CY取反。如果CY为1,执行该指令后CY为0;反之亦然,如表6.83所示。
表6.83 CPL C指令的内容
1)ANL C,bit
该指令对进位标志CY和一个比特位做逻辑与操作,结果保存在CY中,如表6.84所示。
表6.84 ANL C,bit指令的内容
注意: 在操作码后面跟着一字节的位地址。
2)ANL C,/bit
该指令对进位标志CY和一个比特位取反后做逻辑与操作,结果保存在CY中,如表6.85所示。
表6.85 ANL C,/bit指令的内容
注意: 在操作码后面跟着一字节的位地址。
【例6-32】 假设P1端口的第0位为1,且累加器A的第7位为1,同时溢出标志OV的内容为0,执行指令:
1)ORL C,bit
该指令把进位标志CY的内容和比特位内容做逻辑或操作,结果保存在CY中,如表6.86所示。
表6.86 ORL C,bit指令的内容
注意: 在操作码后面跟着一字节的位地址。
2)ORL C,/bit
该指令把进位标志CY的内容和比特位内容取反后做逻辑或操作,结果保存在CY中,如表6.87所示。
表6.87 ORL C,/bit指令的内容
注意: 在操作码后面跟着一字节的位地址。
【例6-33】 假设P1端口的第0位为1,或者累加器A的第7位为1,或者溢出标志OV的内容为0,执行指令:
1)MOV C,bit
该指令把一个比特位的值复制到进位标志CY中,且比特位的值不发生变化,如表6.88所示。
表6.88 MOV C,bit指令的内容
注意: 在操作码后面跟着一字节的位地址。
2)MOV bit,C
该指令把进位标志CY的内容复制到一个比特位中,且进位标志CY的值不发生变化,如表6.89所示。
表6.89 MOV bit,C指令的内容
注意: 在操作码后面跟着一字节的位地址。
【例6-34】 假设进位标志CY的初值为1,端口P2中的数据为C5H(11000101B),端口P1中的数据为35H(00110101B),执行指令:
1)JB bit,rel
该指令判断bit位中的数据是否为1,如果为1,则跳转到(PC)+rel指定的目标地址;否则,程序转向下一条指令,该操作不影响标志位,如表6.90所示。
表6.90 JB bit,rel指令的内容
注:在使用助记符编写汇编语言程序时,KeilμVision将助记符中的rel转换成程序存储空间内的一个目标地址。而在生成所对应的机器指令时,并不是直接使用rel所表示的目标地址,而是将其转换成一个相对偏移量rel.address,对于该条指令而言,相对偏移量的计算方法表示为
rel.address=rel(助记符所表示的目标地址)-PC-3
其中,rel.address对应于操作中(PC)+rel中的rel。
因此,读者一定要正确理解助记符中rel的含义,以及操作中rel所表示的含义。对于本条机器指令而言,操作码后面跟着一字节的位地址和一字节的偏移量rel.address,即表示为下面的形式
【例6-35】 假设端口1的数据为CAH(11001010B),累加器A的内容为56H(01010110B)。则执行指令:
结果:
程序跳转到标号LABEL2的地方执行。
2)JNB bit,rel
该指令判断bit中的数据是否为0,如果为0,则程序跳转到(PC)+rel指定的目标地址;否则,程序转向下一条指令,该操作不影响标志位,如表6.91所示。
表6.91 JNB bit,rel指令的内容
注意: 在操作码后面跟着一字节的位地址和一字节的偏移量rel。
【例6-36】 假设端口1的数据为CAH(11001010B),累加器A的内容为56H(01010110B)。则执行指令:
结果:
程序跳转到标号LABEL2的地方执行。
3)JC rel
该指令判断进位标志位CY是否为1,如果为1,则跳转到(PC)+rel指定的目标地址;否则,程序转向下一条指令,该操作不影响标志位,如表6.92所示。
表6.92 JC rel指令的内容
注意: 在操作码后面跟着一字节的偏移量rel。
【例6-37】 假设进位标志CY为0,则执行指令:
结果:
程序跳转到标号LABEL2的地方执行。
4)JNC rel
该指令判断进位标志位CY是否为0,如果为0,则跳转到(PC)+rel指定的目标地址;否则,程序转向下一条指令,该操作不影响标志位,如表6.93所示。
表6.93 JNC rel指令的内容
注意: 在操作码后面跟着一字节的偏移量rel。
【例6-38】 假设进位标志CY为1,则执行指令:
结果:
程序跳转到标号LABEL2的地方执行。
5)JBC bit,rel
该指令判断指定bit位是否为1,如果为1,则将该位清零,并且跳转到(PC)+rel指定的目标地址;否则,程序转向下一条指令,该操作不影响标志位,如表6.94所示。
表6.94 JBC bit,rel指令的内容
注意: 在操作码后面跟着一字节的位地址和一字节的偏移量rel。
【例6-39】 假设累加器A的内容为56H(01010110B),则执行指令:
结果:
程序跳转到标号LABEL2的地方执行,累加器A的内容变为52H(01010010B)。
8051支持有条件和无条件的程序分支指令,这些程序分支指令用于修改程序的执行顺序。
1)ACALL addr11
该指令无条件地调用在指定地址处的子程序。目标地址由递增PC的高5位、操作码的第7~5位和指令第2字节并置组成。所以,所调用的子程序的首地址必须与ACALL后面指令的第1字节在同一个2KB区域内,如表6.95所示。
表6.95 ACALL addr11指令的内容
注意: a 10 a 9 a 8 是11位目标地址的A 10 ~A 8 位。在操作码后面带着一字节目标地址的A 7 ~A 0 位。
【例6-40】 假设堆栈指针的初值为07H,标号SUBRTN位于程序存储器地址为0345H的位置,如果执行位于地址0123H处的指令:
ACALL SUBRTN
结果:
堆栈指针的内容变成09H,内部RAM地址为08H和09H的位置保存的内容为25H和01H,PC值变为0345H。
2)LCALL addr16
该指令无条件地调用首地址为addr16处的子程序。执行该指令时,将PC加3,以获得下一条指令的地址。然后将指令第2、第3字节所提供的16位目标地址加载到PC 15-0 ,程序转向子程序的首地址执行,如表6.96所示。所调用的子程序的首地址可以在64KB的范围内。
表6.96 LCALL addr16指令的内容
注意: 在操作码后面带着一字节目标地址的A 15 ~A 8 位和一字节目标地址的A 7 ~A 0 位。
【例6-41】 假设堆栈指针的初值为07H,标号SUBRTN位于程序存储器地址为1234H的位置,如果执行位于地址0123H处的指令:
LCALL SUBRTN
结果:
堆栈指针的内容变成09H,内部RAM地址为08H和09H的位置保存的内容为26H和01H,PC值变为1234H。
1)RET
该指令将栈顶高地址和低地址字节连续地送给PC的高字节和低字节,并把堆栈指针减2,返回ACALL或LCALL的下一条指令,继续往下执行,该指令的操作不影响标志位,如表6.97所示。
表6.97 RET指令的内容
【例6-42】 堆栈指针的内容为0BH,内部RAM地址为0AH和0BH的位置保存的内容为23H和01H,如果执行指令:
RET
结果:
堆栈指针的内容变成09H,程序将从地址为0123H的地方继续执行。
2)RETI
该指令将从中断服务程序返回,并清除相应的内部中断状态寄存器。CPU在执行RETI后,至少要再执行一条指令,才能响应新的中断请求,如表6.98所示。
表6.98 RETI指令的内容
【例6-43】 堆栈指针的内容为0BH,结束在地址0123H处的指令执行结束期间产生中断,内部RAM地址为0AH和0BH的位置保存的内容为23H和01H,如果执行指令:
RETI
结果:
堆栈指针的内容变成09H,中断返回后继续从程序代码地址为0123H的位置执行。
1)AJMP addr11
该指令实现无条件跳转。绝对跳转操作的目标地址是由PC递增两次后值的高5位、操作码的第7~5位和第2字节并置而成,如表6.99所示。目标地址必须包含AJMP指令后第一条指令的第1字节在内的2KB范围内。
表6.99 AJMP addr11指令的内容
注意: a 10 a 9 a 8 是11位目标地址的A 10 ~A 8 位。在操作码后面带着一字节目标地址的A 7 ~A 0 位。
【例6-44】 假设标号JMPADR位于程序存储器的0123H的位置,如果指令:
AJMP JMPADR
位于程序存储器地址为0345H的位置。
结果:
执行完该指令后,PC的值变为0123H。
2)LJMP addr16
该指令实现无条件长跳转操作,跳转的16位目的地址由指令的第2和第3字节组成,如表6.100所示。因此,程序指向的目标地址可以包含程序存储器的整个64KB空间。
表6.100 LJMP addr16指令的内容
注意: 在操作码后面带着一字节目标地址的A 15 ~A 8 位和一字节目标地址的A 7 ~A 0 位。
【例6-45】 假设标号JMPADR位于程序存储器的1234H的位置,如果指令:
LJMP JMPADR
位于程序存储器地址为1234H的位置。
结果:
执行完该指令后,PC的值变为1234H。
3)SJMP rel
该指令实现无条件短跳转操作,跳转的目的地址是由PC递增两次后的值和指令的第2字节带符号的相对地址相加而成的,如表6.101所示。
表6.101 SJMP rel指令的内容
注意: 在操作码后面带着一字节的相对偏移量rel。
【例6-46】 假设标号RELADR位于程序存储器的0123H的位置,如果指令:
SJMP RELADR
位于程序存储器地址为0100H的位置。
结果:
执行完该指令后,PC的值变为0123H。
注:在上面这个例子中,紧接SJMP的下一条指令的地址是0102H,因此跳转的偏移量为0123H-0102H=21H。
4)JMP@A+DPTR
该指令实现无条件的跳转操作,跳转的目标地址是将累加器A中的8位无符号数与数据指针DPTR的内容相加而得。相加运算不影响累加器A和数据指针DPTR的原内容,如表6.102所示。若相加结果大于64KB,则从程序存储器的零地址往下延续。
表6.102 JMP@A+DPTR指令的内容
【例6-47】 假设累加器A中的值是偶数(0~6)。下面的指令序列将使程序跳转到位于跳转表JMP_TBL的4条AJMP指令中的某一条去执行:
如果开始执行上面指令时,累加器A中的值为04H,那么程序最终会跳到标号为LABEL2的地方执行。
注意: AJMP是一个2字节指令,所以在跳转表中,各个跳转指令的入口地址依次相差2字节。
1)JNZ rel
该指令实现有条件跳转。判断累加器A的内容是否不为0,如果不为0,则跳转到(PC)+rel指定的目标地址;否则,程序转向下一条指令,如表6.103所示。
表6.103 JNZ rel指令的内容
注意: 在操作码后面带着一字节的偏移量rel。
【例6-48】 假设累加器A的内容为00H,则执行指令:
结果:
程序跳转到标号LABEL2的地方执行。
2)JZ rel
该指令实现有条件跳转。判断累加器A的内容是否为0,如果为0,则跳转到(PC)+rel指定的目标地址;否则,程序转向下一条指令,如表6.104所示。
表6.104 JZ rel指令的内容
注意: 在操作码后面带着一字节的偏移量rel。
【例6-49】 假设累加器A的内容为01H,则执行指令:
结果:
程序跳转到标号LABEL2的地方执行。
3)CJNE A,direct,rel
该指令对累加器A和直接寻址单元内容相比较,若它们的值不相等,则程序转移到(PC)+rel指向的目标地址。若直接寻址单元的内容小于累加器内容,则清除进位标志CY;否则,置位进位标志CY,如表6.105所示。
表6.105 CJNE A,direct,rel指令的内容
注意: 在操作码后面跟着一字节的直接地址和一字节的偏移量rel。
4)CJNE A,#data,rel
该指令将比较累加器A的内容和立即数,若它们的值不相等,则程序转移(PC)+rel指向的目标地址。进位标志CY设置同上,该指令不影响累加器A的内容,如表6.106所示。
表6.106 CJNE A,#data,rel指令的内容
注意: 在操作码后面跟着一字节的立即数和一字节的偏移量rel。
5)CJNE Rn,#data,rel
该指令将寄存器Rn的内容和立即数进行比较,若它们的值不相等,则程序转移到(PC)+rel指向的目标地址。进位标志CY设置同上,如表6.107所示。
表6.107 CJNE Rn,#data,rel指令的内容
注意: rrr为寄存器的编号,因此机器码范围是B8H~BFH。在操作码后面跟着一字节的立即数和一字节的偏移量rel。
6)CJNE@Ri,#data,rel
该指令将间接寻址的内容和立即数相比较,若它们的值不相等,则程序转移到(PC)+rel指向的目标地址。进位标志CY设置同上,如表6.108所示。
表6.108 CJNE@Ri,#data,rel指令的内容
注意: i表示R0或者R1。当i=0时,表示R0寄存器;当i=1时,表示R1寄存器。在操作码后面跟着一字节的立即数和一字节的偏移量rel。
【例6-50】 假设累加器A的内容为34H,寄存器R7的内容为56H。则执行指令:
结果:
第一条指令将进位标志CY设置为1,程序跳转到标号NOT_EQ的地方。接着测试进位标志CY,可以确定寄存器R7的内容大于还是小于60H。
7)DJNZ Rn,rel
该指令实现有条件跳转。每执行一次指令,寄存器Rn的内容减1,并判断其内容是否为0。若不为0,则转向(PC)+rel指向的目标地址,继续执行循环程序,否则,结束循环程序,执行下一条指令,如表6.109所示。
表6.109 DJNZ Rn,rel指令的内容
注意: rrr为寄存器的编号,因此机器码范围是D8H~DFH。在操作码后面跟着一字节的偏移量rel。
8)DJNZ direct,rel
该指令实现有条件跳转。每执行一次指令,直接寻址单元的内容减1,并判断其内容是否为0。若不为0,则转向(PC)+rel指向的目标地址,继续执行循环程序,否则,结束循环程序,执行下一条指令,如表6.110所示。
表6.110 DJNZ direct,rel指令的内容
注意: 在操作码后面跟着一字节的直接地址和一字节的偏移量rel。
【例6-51】 假设内部RAM地址为40H、50H和60H的单元分别保存着数据01H、70H和15H,则执行指令:
结果:
程序将跳转到标号LABEL_2处执行,且相应的3个RAM单元的内容变成00H、6FH和15H。
NOP指令表示无操作,如表6.111所示。
表6.111 NOP指令的内容
【例6-52】 假设期望在端口P2的第7位引脚上输出一个长时间的低电平脉冲,该脉冲持续5个机器周期(精确)。若仅仅使用SETB和CLR指令序列,生成的脉冲只能持续一个机器周期。因此,需要设法增加4个额外的机器周期,可以按照下面的方式实现所要求的功能(假设在此期间没有使能中断):