3.2 MCS-51单片机指令介绍

在汇编程序指令编写和程序注释过程中,会用到一些特殊符号,具体含义如下。

Rn:当前工作寄存器组中的任一寄存器(n=0~7)。

Ri:当前工作寄存器组中的R0和R1(i=0,1),Ri常用作间接寻址寄存器。

@:寄存器间接寻址或变址寻址符号。

(Ri):由Ri间接寻址指向的地址单元。用DPTR间接寻址时,含义相同。

((Ri)):由Ri间接寻址指向的地址单元中的内容。用DPTR间接寻址时,含义相同。

(XXH):某内部RAM单元中的内容。

Direct:内部RAM单元(包括SFR区)的直接地址(也有的写成dir)。

#Data:8位数据。

#Data16:16位数据。

Addr16:16位地址。

Addr11:11位地址。

Rel:由8位补码数构成的相对偏移量。

Bit:位地址,内部RAM和特殊功能寄存器的直接寻址位。

→:数据流向指示。

3.2.1 数据传送指令

数据传送指令共有29条,是指令系统中数量最多、使用非常频繁的指令。

1.以累加器为目的操作数的指令(4条)

【例3.1】 已知R0=25H,(25H)=0AAH,下面指令执行后的结果分析如下。

2.以寄存器Rn为目的操作数的指令(3条)

【例3.2】 已知A=26H,R5=75H,(62H)=0ACH,下面指令执行后的结果分析如下。

注意:当操作数中出现16进制数据的高8位为A~F等字母时,需要在前面加上数字0,如ACH,需要在前面加上0,写为0ACH,否则会出错。

3.以直接地址Direct为目的操作数的指令(5条)

【例3.3】 设A=36H,(40H)=19H,(25H)=11H,R0=24H,(24H)=62H。下面指令执行后的结果分析如下。

4.以间接地址@Ri为目的操作数的指令(3条)

5.16位数据传送指令(1条)

指令执行的操作是将16位的立即数#Data传送到16位寄存器DPTR中。其中高8位的数据DataH送入DPH,低8位的数据DataL送入DPL。

例如:

6.外部数据传送指令(4条)

在MCS-51单片机指令系统中,下面4条指令操作用于单片机对外部RAM或者外部I/O端口的数据传送。

上述四条指令中采用了两种指针对外部RAM或I/O端口进行间接寻址:8位的工作寄存器Ri和16位的数据指针DPTR,Ri寻址外部RAM的00H~0FFH单元,共256字节单元;DPTR寻址外部RAM或I/O端口的0000H~0FFFFH单元,共64KB。

7.访问ROM的指令(2条)

这两条指令也称查表指令。编程时,预先在程序存储器中建立数据表格,以后程序运行时利用这两条指令查表。这两条指令都为单字节指令,不同的是,第一条指令的基本地址为程序计数器,偏移地址为A;而第二条指令中,16位数据指针DPTR和A既可以作为基本地址,也可以作为偏移地址,使用比较灵活。因此,可以看出第一条指令查找范围为256B,而第二条指令查找范围可达整个ROM的64KB。

8.数据交换指令(5条)

其中,进行的操作是A与Rn(Rn=R0~R7)、Direct和@Ri(Ri=R0、R1)所寻址的单元内容,以及自身半字节的内容进行互换。其中,前三条指令为字节交换,而后面两条指令进行的是半字节交换,XCHD完成低4位的交换而高4位不变,SWAP完成A自身的低4位与高4位的交换。

9.堆栈操作指令(2条)

上述两条指令中,PUSH为入栈指令,POP为出栈指令,用于保护和恢复现场。它们都是双字节指令,都不影响标志位。

入栈操作时,栈指针SP首先上移一个单元,指向栈顶的上一个单元,接着将直接地址Direct单元内容压入当前SP指向的单元中。出栈操作时,首先将栈指针SP所指向的单元的内容弹出到Direct中,然后SP下移一个单元,指向新的栈顶。

堆栈操作的特殊性如下。

① 堆栈指令仅用于内部RAM的128字节单元或专用寄存器的操作;

② 堆栈操作必须遵循“先进后出”或者“后进先出”的原则,否则堆栈中的数据会出现混乱。

3.2.2 算术运算指令

算术运算指令共有24条,包括执行加、减、乘、除的指令和执行加1、减1、BCD码的运算和调整的指令。虽然MCS-51单片机的算术逻辑单元(ALU)仅能对8位无符号整数进行运算,但利用进位标志C,可进行多字节无符号整数的运算。此外,利用溢出标志,还可以对带符号数进行补码运算。需要指出的是,除加1、减1指令外,其他指令的执行对程序状态字(PSW)有影响。

1.加法指令(4条)

加法指令将Rn(R0~R7)、Direct、@Ri(Ri=R0,R1)及#Data与A相加,运算结果保存在A中。上面4条指令的执行将影响标志位AC、CY、OV、P。当和的第3位或第7位有进位时,分别将AC、CY标志位置1,否则为0。溢出标志位只有带符号数运算时才有用。OV=1也可以理解为:由于进位破坏了符号位的正确性。

2.带进位加指令(4条)

这组指令完成的功能是将Rn、Direct、@Ri及#Data,连同进位标志位CY,与A的内容相加,运算结果保存在A中。其他功能与ADD指令相同。

3.带借位减法指令(4条)

注意:没有不带借位标志的减法指令,所以当两个单字节或多字节最低位相减时,必须先清除CY。当两个不带符号位的数相减时,溢出与否与OV状态无关,而根据CY是否有借位来判断。

4.十进制调整指令(1条)

十进制调整指令用于对BCD码十进制数加法运算的结果进行修正。其指令格式为

该指令的功能是对压缩的BCD码(一字节存放2位BCD码)的加法结果进行十进制调整。两个BCD码按二进制相加之后,必须经本指令的调整才能得到正确的压缩BCD码。对于十进制数(BCD码)的加法运算,须借助于二进制加法指令。

5.增1指令(5条)

这5条指令将指令中的变量加1,且不影响程序状态字PSW中的任何标志位。若变量原来为0FFH,加1后将溢出为00H(前4条指令),标志位也不会受到影响。第5条指令是16位数加1指令。指令首先对低8位指针DPL的内容执行加1操作,当产生溢出时,就对DPH的内容进行加1操作,也不影响标志位CY的状态。

6.减1指令(4条)

这4条指令的功能是将指定的变量减1。若原来为00H,减1后下溢出为0FFH,不影响标志位(P标志位除外)。

7.乘法指令(1条)

这条指令的功能是把A和B中的无符号8位整数相乘,其16位积的低8位在A中,高8位在B中。如果积大于255,则溢出标志位OV置1,否则OV清0。进位标志位CY清0。

8.除法指令(1条)

该指令的功能是用A中8位无符号整数(被除数)除以B中8位无符号整数(除数),所得的商(为整数)存放在A中,余数存放在B中,且CY和溢出标志位OV清0。如果B的内容为“0”(即除数为“0”),则存放结果的A、B中的内容不定,溢出标志位OV置1。

【例3.4】(A)=0FBH,(B)=12H,执行指令

结果为(A)=0DH,(B)=11H,CY=0,OV=0。

3.2.3 移位与逻辑运算指令

移位与逻辑运算指令共有24条,有左/右移位、清0、取反、与、或、异或等逻辑操作。这类指令一般会影响奇偶标志位P,循环指令会影响CY。

1.移位操作(4条)

第一条指令的功能是A的8位向左循环移一位,第7位循环移入第0位,不影响标志位。

第二条指令的功能是A的内容向右循环移一位,第0位移入第7位。

第三条指令的功能是将A的内容和进位标志位CY一起向左循环移一位,A的第7位移入进位标志位CY,CY移入A的第0位,不影响其他标志位。

第四条指令的功能是A的内容和CY一起向右循环移一位,A的第0位移入CY,CY移入A的第7位。

2.清零和取反(2条)

第一条指令的功能是A清0,不影响CY、OV等标志位。

第二条指令的功能是将A的内容按位逻辑取反,不影响标志位。

3.逻辑与指令(6条)

这组指令的功能是在指定的变量之间以位为基础进行“逻辑与”操作,结果存放到目的变量所在的寄存器或存储器中。

4.逻辑或指令(6条)

这组指令的功能是在所指定的变量之间执行以位为基础的“逻辑或”操作,结果存到目的变量寄存器或存储器中。

5.逻辑异或指令(6条)

这组指令的功能是在所指定的变量之间执行以位为基础的“逻辑异或”操作,结果存到目的变量寄存器或存储器中。

3.2.4 控制转移指令

控制转移指令可以改变PC的内容,从而改变程序运行的顺序,将程序跳转到某个指定的地址,再执行下去。程序转移指令共有17条。所有指令的目标地址都应在64KB的程序存储器地址范围内。除NOP指令执行时间为1个机器周期外,其他指令的执行时间都是2个机器周期。

1.无条件转移指令(1条)

该条指令是代码在2KB范围内的无条件跳转指令。AJMP把AT89C51单片机的64KB程序存储器空间划分为32个区,每个区为2KB范围,转移目标地址必须与AJMP下一条指令的第一字节在同一2KB范围内(即转移的目标地址必须与AJMP下一条指令地址的高5位地址码相同),否则将引起混乱。执行该指令时,先将PC加2(本指令为2B),然后把Addr11送入PC.10~PC.0,PC.15~PC.11保持不变,程序转移到目标地址。

2.相对转移指令(1条)

这是无条件转移指令,其中Rel为相对偏移量,是一个单字节的带符号8位二进制补码数,因此它所能实现的程序转移是双向的。Rel如为正,则向地址增大的方向转移;Rel如为负,则向地址减小的方向转移。执行该指令时,在PC加2(本指令为2B)之后,把指令的有符号的偏移量Rel加到PC上,并计算出目标地址,因此跳转的目标地址可以在与这条指令相邻的下一条指令的前128B到后127B(-128~+127)之间。用户在编写程序时,只需要在相对转移指令中直接写上要转向的目标地址标号就可以了,相对偏移量由汇编程序自动计算。例如:

程序在汇编时,转移到LOOP处的偏移量由汇编程序自动计算和填入。

3.长跳转指令(1条)

这条指令执行时,把跳转的目标地址,即指令的第二和第三字节分别装入PC的高位和低位字节中,无条件地转向Addr16指定的目标地址。目标地址可以在64KB程序存储器地址空间的任何位置。

4.间接跳转指令(1条)

这是一条单字节的转移指令,转移的目标地址由A中8位无符号数与DPTR的16位无符号数内容之和来确定。该指令以DPTR内容作为基址,A的内容作为变址。因此,只要DPTR的值固定,而给A赋予不同的值,即可实现程序的多分支转移。

5.条件转移指令(2条)

条件转移即程序的转移是有条件的。执行条件转移指令时,如指令中规定的条件满足,则进行转移;条件不满足,则顺序执行下一条指令。转移的目标地址在以下一条指令地址为中心的256B范围内(-128~+127)。当条件满足时,PC装入下一条指令的第一字节地址,再把带符号的相对偏移量Rel加到PC上,计算出要转向的目标地址,条件转移指令有两条。

6.比较不相等转移指令(4条)

这组指令的功能是比较前面两个操作数的大小,如果它们的值不相等则转移,在PC加上下一条指令的起始地址后,把指令最后1字节的有符号的相对偏移量加到PC上,并计算出转向的目标地址。如果第一操作数(无符号整数)小于第二操作数(无符号整数),则进位标志位CY置1,否则CY清0。该指令的执行不影响任何一个操作数的内容。

7.减1不为0转移指令(2条)

这是一组把减1与条件转移两种功能结合在一起的指令,共有两条指令:

这组指令将源操作数(Rn或Direct)减1,结果回送到Rn或Direct。如果结果不为0则转移。本指令允许程序员把Rn或内部RAM的Direct用作程序循环计数器。

这两条指令主要用于控制程序循环。如预先把Rn或内部RAM的Direct装入循环次数,则利用本指令,以减1后是否为0作为转移条件,即可实现按次数控制循环。

8.调用子程序指令(2条)

调用子程序指令包括短调用指令(ACALL)和长调用指令(LCALL)。

ACALL指令也是2KB范围内的调用子程序的指令。执行时先把PC加2(本指令为2B),获得下一条指令地址,把该地址压入堆栈中保护,即堆栈指针SP加1,PCL进栈,SP再加1,PCH进栈。最后把PC的高5位和指令代码中的11位地址Addr11连接,获得16位的子程序入口地址,并送入PC,转向执行子程序。所调用的子程序地址必须与ACALL指令下一条指令的第一字节地址在同一个2KB区域内,否则将引起程序转移混乱。由于在执行调用操作之前PC先加了2,因此如果ACALL指令正好落在区底的两个单元内,程序就转移到下一个区中了。

LCALL指令可以调用64KB范围内程序存储器中的任何一个子程序。指令执行时,先把PC加3,获得下一条指令的地址(断点地址),并把它压入堆栈(先低位字节,后高位字节),同时把堆栈指针加2。接着把指令的第二和第三字节分别装入PC的高位和低位字节中,然后从PC指定的地址开始执行程序。

9.子程序的返回指令

执行本指令时,

其功能是从堆栈中退出PC的高8位和低8位字节,把堆栈指针减2,从PC指定的地址开始执行程序。

10.中断返回指令

其功能和RET指令相似,两条指令的不同之处在于该指令清除了在中断响应时被置1的AT89C51单片机内部中断优先级寄存器的中断优先级状态,其他操作均与RET指令相同。

11.空操作指令

CPU不进行任何实际操作,只消耗一个机器周期的时间,且只执行(PC)+1→PC操作。NOP指令常用于程序中的等待或时间延迟。

3.2.5 位操作指令

AT89C51单片机内部有一个位处理机,其位操作指令共有17条。

1.数据位传送指令(2条)

这两条指令的功能是把由源操作数指定的位变量送到目的操作数指定的单元中。其中一个操作数必须为进位标志,另一个可以是任何直接寻址位。该指令不影响其他寄存器或标志位。

2.位变量修改指令(6条)

这6条指令实现对C(CY)或者bit中的内容进行清0、取反或置1。这些指令不影响除C以外的其他标志位。

3.位变量逻辑与指令(2条)

这两条指令完成的是对C与bit中的内容或该位内容的取反进行逻辑与操作,结果返回C中。

4.位变量逻辑或指令(2条)

这两条指令完成的是对C与bit中的内容或该位内容的取反进行逻辑或操作,结果返回C中。

5.条件转移类指令(5条)

这5条指令中,前4条指令根据C或者bit是否为1或0,满足条件则跳转,但这些指令执行完毕后C或bit本身不会改变;而第5条指令执行完毕后,如果(bit)=1,程序跳转到Rel并将bit清0,即(bit)=0。