2.2 微机指令系统
2.2.1 指令系统及指令格式
每种计算机都定义了自己的指令系统。指令系统包括寻址方式和指令集两部分内容。指令寻找操作数地址的方式即寻址方式。一种CPU能够支持的所有指令的集合称为指令集。计算机的指令系统是影响计算机性能和应用的重要指标之一。
MCS-51单片机的指令系统是一种简明高效、易于掌握的指令系统。其基本指令共111条:按照指令占用的存储字节数,可分为单字节指令49条,双字节指令45条,三字节指令17条;按照执行指令需要的机器周期数,可分为单周期指令64条,双周期指令45条,四周期指令2条(乘法指令MUL和除法指令DIV)。由此可见,MCS-51单片机指令系统对存储空间和机器时间的利用效率较高。
计算机能够直接执行的程序是以二进制格式存储的机器语言程序。机器语言不容易记忆,阅读和编写困难,为了克服这个缺点,人们为每条机器语言指令都编写了对应的助记符,称为助记符指令。助记符指令和机器语言指令是一一对应的。可以用计算机程序把助记符程序翻译为机器语言程序,这个过程称为汇编,助记符语言也称为为汇编语言。本章介绍的指令系统以汇编语言的形式进行描述。
一条MCS-51单片机的汇编语言指令最多包含4个区段,如下所示:
[标号:] 操作码 [操作数] [;注释]
4个区段之间要用分隔符隔开:标号和操作码之间用冒号“:”隔开,操作码和操作数之间用空格隔开,操作数和注释之间用分号“;”隔开。如果存在多个操作数,之间要用逗号“,”隔开(MUL和DIV指令除外,它们的操作数固定为“AB”,中间没有分隔符)。
标号代表该指令的首字节在存储器中的存放地址,标号也称为“符号地址”。标号一般用在要作为跳转目标的指令前,这样可以方便编程。标号区段为可选项,指令前可以不加标号。标号由用户定义,可使用英文字母、数字等组成标号,标号的第一个字符必须为大写英文字母或下划线。在同一个程序中一个标号只能使用一次。
操作码说明指令的功能,这一个区段不能缺少。MCS-51单片机指令系统中共有42种助记符,代表着33种不同的功能。如“MOV”是数据传输功能的助记符。
操作数给出指令要处理的数据或数据的存放地址。根据指令功能的不同,操作数的个数也不同,MCS-51单片机的指令,可以有一个操作数、两个操作数、三个操作数或没有操作数。例如指令“MOV A,R2”中,MOV是操作码,表示数据传送,后面带有两个操作数,前一个操作数A为目标操作数,第二个操作数R2为源操作数,该指令的功能是把工作寄存器R2的内容传送到累加器A中。
注释为可选项。使用注释的目的是方便阅读,提高调试效率,并有利于程序代码的后期维护和重复利用。
2.2.2 寻址方式
寻址方式即寻找操作数的地址的方式。
指令执行的本质上是对数据进行处理的过程,指令的操作码部分规定操作的种类,操作数部分则给出参与操作的数据,这些数据或直接给出,或按照某种规律给出地址。
在使用汇编语言编程时,数据的存放、传送、运算都要通过指令来完成,编程者自始至终都要非常清楚操作数的位置,以及如何将它们传送到适当的寄存器中去参与运算。每一种计算机都具有多种寻址方式,寻址方式是否灵活高效是影响计算机性能的重要指标之一。寻址方式是汇编语言程序设计的基础,必须熟练掌握。
在MCS-51单片机中,有以下7种寻址方式:
①寄存器寻址;
②立即寻址;
③直接寻址;
④寄存器间接寻址;
⑤基址寄存器加变址寄存器间接寻址;
⑥相对寻址;
⑦位寻址。
1.寄存器寻址
操作数存放在寄存器中的寻址方式称为寄存器寻址。寄存器包括工作寄存器R0~R7,以及累加器A、寄存器B、布尔处理器的位累加器C和数据指针DPTR。在这种寻址方式下,用来存放操作数的寄存器信息已经包含在操作码字节内,因此寄存器寻址的操作数信息不再单独占用指令字节。
例如,指令MOV A,R1中的源操作数R1和目标操作数A都是寄存器,使用的寻址方式都是寄存器寻址,所以这条指令的机器代码只占用一个字节的程序存储器。
2.立即寻址
在指令字节中直接给出常数作为操作数的寻址方式称为立即寻址,该操作数称为立即数。立即数存储在程序存储器中,紧跟在操作码的后面进行存储。立即数可以是1个字节的,也可以是2个字节的,在指令代码中相应占用1个字节或2个字节。符号“#”为立即数标志。
例如:MOV A,#61H 对应机器码:74H 61H(74H代表“MOV A,#data”)。
上面指令中的“#61H”就是1个字节的立即数,它用到的寻址方式就是立即寻址。
例如:MOV DPTR,#1234H 对应机器码 90H 12H 34H。
上面指令中的#1234H就是2个字节的立即数。
3.直接寻址
在指令字节中直接给出操作数地址的寻址方式称为直接寻址。直接寻址是访问特殊功能寄存器区(内部RAM 80H~FFH单元)的唯一寻址方式。直接寻址还可访问内部RAM低128字节的内存区域。
例如:MOV 10H,#20H;把立即数20H放入内部RAM中地址为10H的存储单元。
指令中目标操作数“10H”使用的寻址方式就是直接寻址。注意直接寻址和立即寻址的区别是立即寻址标志“#”。直接地址占用一个字节的存储单元。
4.寄存器间接寻址
在指令字节中给出间接寻址寄存器,该寄存器的内容是要寻址的操作数的地址,这种寻址方式称为寄存器间接寻址。
访问内部RAM区时,可使用R0、R1作为间接寻址寄存器,寻址低128字节RAM区和高128字节RAM区。用MOVX指令访问外部RAM时,可使用16位寄存器DPTR作为间接寻址寄存器;也可以使用R0、R1作为间接寻址寄存器,此时由P2口输出操作数存放单元的高8位地址,R0和R1中放入操作数存放单元的低8位地址;寻址范围均为0000H~FFFFH共64KB地址空间。
寄存器间接寻址的标志是“@”。例如指令MOV A,@R0中,源操作数使用的寻址方式就是寄存器间接寻址。R0中存放的并不是源操作数,而是源操作数的存放地址(图2-25)。因为间接寻址寄存器都是可使用寄存器寻址方式的寄存器,所以间接寻址和寄存器寻址一样,操作数地址信息已包含在操作码内,不再另外占用存储单元。
图2-25 间接寻址方式堆栈指针
堆栈指针SP在进栈、出栈指令执行时的作用和间接寻址寄存器类似,也可以算作一个间接寻址寄存器。
5.基址寄存器加变址寄存器间接寻址
在对程序存储器中的常数和表格等数据寻址时使用的寻址方式为基址寄存器加变址寄存器间接寻址。它以基址寄存器DPTR或PC中内容为基本地址,加上变址寄存器A中内容作为操作数的地址。变址寄存器A中内容为无符号数学与运算。
使用这种寻址方式的指令一共有三条:
MOVC A,@A+DPTR
MOVC A,@A+PC
JMP @A+DPTR
6.相对寻址
在相对转移指令中给出转移目标地址的寻址方式称为相对寻址。这种寻址方式是以程序执行时PC的当前值为基本地址,加上指令中给出的偏移量得到转移目标地址。指令中给出的偏移量是一个字节的带符号常数,取值范围为–128~+127。
例如:JZ 10H;当(A)=0时,跳转到(PC)+10H得到目标地址。
7.位寻址
在位操作指令中直接给出位操作数地址的寻址方式称为位寻址。
MCS-51单片机具有很强的位操作能力。为方便位操作,许多特殊功能寄存器中的位都具有位地址,有的还有位名称。位地址和位名称在位操作指令中都可以直接使用。位寻址方式的寻址范围为内部RAM 20H~2FH的128个位(位地址为00H~7FH)和SFR中的可位寻址位。
例如:
MOV C,80H;C为可位寻址位
8.指令的分类和符号说明
MCS-51单片机的指令按其功能可分为下列5类:
①数据传送类;
②算术运算类;
③逻辑运算类;
④位操作类;
⑤控制转移类。
在描述指令的功能时,要用到一些符号(通配符),这些符号的含义如下:
Rn——当前选定的工作寄存器区的工作寄存器R0~R7,n=0~7;
Ri——可用于寄存器间接寻址的两个工作寄存器R0、R1,即i=0,1;
direct——8位直接地址,可访问内部RAM区和特殊功能寄存器区;
#data——指令中的8位常数,立即数;
#data16——指令中的16位常数,立即数;
addr16——16位的目标地址,用于LJMP、LCALL指令,可指向64KB程序存储器的任一存储单元;
addr11——11位的目标地址,用于AJMP、ACALL指令,可指向PC当前所指区域2KB范围内的存储单元;
rel——8位带符号的相对偏移量,偏移量相对于下一条指令的首地址计算,取值范围为–128~+127;
bit——内部RAM或特殊功能寄存器区的可位寻址位;
A——累加器A;
B——寄存器B,用于MUL指令和DIV指令;
C——PSW中的进位标志位Cy,也用作位处理器的位累加器;
DPTR——数据指针;
#——立即数标志;
@——间接寻址标志,用于寄存器间接寻址和基址寄存器加变址寄存器间接寻址;
/——位操作数的前缀,表示该位先取反,再进行处理;
(X)——地址为X的存储单元的内容;
((X))——以地址为X的存储单元的内容为地址的存储单元的内容;
←——箭头左边的内容被箭头右边的内容所代替。
2.2.3 数据传送指令
数据传送指令是编程时使用最频繁的一类指令,见表2-11。
表2-11 数据传送类指令一览表
数据传送指令的作用是把源操作数传送给目标操作数,指令执行后,源操作数保持不变,目标操作数的内容被源操作数的内容代替。
数据传送类指令共28条,用到的助记符有MOV,MOVX,MOVC,XCH,XCHD,PUSH,POP等。源操作数可以使用寄存器寻址、立即数寻址、直接寻址、寄存器间接寻址、基址加变址间接寻址5种寻址方式,目标操作数可以采用寄存器寻址、直接寻址、寄存器间接寻址3种寻址方式。
除了直接以PSW为目标操作数的指令外,数据传送类指令不影响标志位的状态。这里说的标志位指Cy、AC和OV,不包括随累加器A的内容而改变的奇偶标志位P。
1.数据传送到累加器A的指令
MOV A,Rn ;A←(Rn) MOV A,direct ;A←(direct) MOV A,@Ri ;A←((Ri)) MOV A,#data ;A←data
这组指令的功能是把源操作数的内容送入累加器A,源操作数有寄存器寻址、直接寻址、寄存器间接寻址、立即寻址等寻址方式,例如:
MOV A,R0 ;寄存器寻址 MOV A,7FH ;直接寻址 MOV A,@R1 ;寄存器间接寻址 MOV A,#20H ;立即寻址
2.数据传送到寄存器Rn的指令
MOV Rn,A ;Rn←(A) MOV Rn,direct ;Rn←(direct) MOV Rn,#data ;Rn←data
这组指令的功能是把源操作数的内容传送到寄存器Rn中,n=0,1,…,7。源操作数可以是累加器A,或直接寻址,或立即寻址。例如:
MOV R0,A ;累加器A的内容送当前工作寄存器组的R0 MOV R1,P0 ;P0是特殊功能寄存器,使用直接寻址方式访问 MOV R2,#100 ;#100为立即数,不加后缀即为十进制数100
3.数据传送到直接寻址单元的指令
MOV direct,A ;direct←(A) MOV direct,Rn ;direct←(Rn) MOV direct,direct ;direct←(direct) MOV direct,@Ri ;direct←((Ri)) MOV direct,#data ;direct←data
这组指令的功能是把源操作数的内容传送到直接寻址单元中。可直接寻址的存储单元包括包括地址为00H~7FH的低128字节RAM区和地址为80H~FFH的高128字节的特殊功能寄存器区。源操作数可以是累加器A、工作寄存器Rn、直接寻址单元、寄存器间接寻址的内部RAM单元或立即数。例如:
MOV 20H,A ;累加器A内容送内部RAM地址为20H的单元 MOV20H,R1 ;寄存器R1的内容送内部RAM地址为20H的单元 MOV 30H,40H ;内部RAM地址40H单元内容送内部RAM地址20H的单元 MOV 30H,@R0 ;R0的内容为地址的内部RAM单元内容送内部RAM30H单元 MOV TMOD,#33H ;立即数#33H送特殊功能寄存器TMOD
4.数据传送到间接寻址的内部RAM单元的指令
MOV @Ri,A ;(Ri)←(A) MOV @Ri,direct ;(Ri)←(direct) MOV @Ri,#data ;(Ri)←data
这组指令的功能是把源操作数传送到间接寻址的内部RAM单元中。间接寻址的内部RAM单元包括地址为00H~7FH的低128字节RAM区和只有52子系列的MCS-51单片机具有的地址为80H~FFH的高128字节的RAM区。源操作数可以是累加器A、直接寻址RAM单元或立即数。例如:
MOV @R0,A ;累加器A的内容送以R0的内容为地址的存储单元 MOV @R1,SBUF ;SBUF的内容送以R1的内容为地址的存储单元 MOV @R1,#00111100B ;立即数00111100B送以R1的内容为地址的存储单元
5.16位立即数传送到DPTR的指令
MOV DPTR,#data16 ;DPTR←data16
这条指令的功能是把16位的立即数送入数据指针DPTR,其中高8位数据送入特殊功能寄存器DPH,低8位数据送入特殊功能寄存器DPL。例如:
MOV DPTR,#1234H;立即数12H送入DPH,立即数34H送入DPL
6.程序存储器内容送累加器A(查表指令)
MOVC A,@A+DPTR ;A←((A)+(DPTR)) MOVC A,@A+PC ;A←((A)+(PC))
MOVC指令的功能是把存储在程序存储器中的源操作数传送到累加器A。MOVC指令经常用于查找存放在程序存储器中的常数表格,故也称作查表指令。源操作数使用基址寄存器加变址寄存器间接寻址的寻址方式。
第一条指令以数据指针DPTR作为基址寄存器,执行时用A的内容作为无符号数加上DPTR的内容得到16位的地址,然后将程序存储器中该地址单元的内容传送到累加器A。由于DPTR的内容可任意设定,这条指令可查询存放在64KB程序存储器空间的任何位置的表格,表格的大小也没有限制。
第二条指令以程序计数器PC作为基址寄存器,执行时用A的内容作为无符号数加上PC的内容得到16位的地址,然后将程序存储器中该地址单元的内容传送到累加器A。由于程序执行时PC的内容总是固定的指向下一条指令首字节的存储地址,这条指令可查询的表格必须存放这条查表指令之后的256个存储单元的范围内,表格的大小也受到限制。
7.累加器A与外部数据存储器之间的数据传送指令
MOVX A,@Ri ;A←((Ri)) MOVX A,@DPTR ;A←((DPTR)) MOVX @Ri,A ; (Ri)←(A) MOVX @DPTR,A ; (DPTR)←(A)
这组指令的功能是在累加器A和外部数据存储器或外部扩展I/O接口之间进行数据传送。前两条MOVX指令执行时,(P3.7)引脚上输出低电平有效信号;后两条MOVX指令执行时,(P3.6)引脚上输出低电平有效信号。当使用DPTR作为间接寻址寄存器时,DPTR中存放全部16位的地址信息;当使用R0、R1作为间接寻址寄存器,特殊功能寄存器P2中存放高8位地址,R0和R1中存放低8位地址。MOVX指令执行的时序见图2-7和图2-8。
8.堆栈操作指令
PUSH direct ;SP←(SP)+1,(SP)←(direct) POP direct ;direct←((SP)),SP←(SP)-1
这组指令的功能是对堆栈进行操作。PUSH指令的功能是把直接寻址方式给出的源操作数压入堆栈的栈顶,POP指令的功能是从堆栈的栈顶弹出一个数传送到直接寻址方式给出的目标操作数。由于PUSH和POP指令的操作数只能采用直接寻址方式,故对累加器A的内容进行堆栈操作时,需写作“PUSH ACC”和“POP ACC”。
堆栈是在RAM中开辟出来的一块按照“先入后出”原则进行管理的存储区域。堆栈主要用于子程序调用和返回过程中的断点保护和现场保护,也可以用于主程序和子程序之间的参数传递。对堆栈进行操作时需要用堆栈指针SP来指示出堆栈的位置。
MCS-51单片机中的堆栈是一个“向上生长”的堆栈。当执行PUSH指令时,首先SP的值自动加1,然后把需要入栈的数据传送到SP指向的新的栈顶;当执行POP指令时,首先从栈顶取出数据,然后SP的值会自动减1,指向新的栈顶。
当单片机复位时,SP的值为07H,进栈数据会占用工作寄存器区的空间,因此在用户初始化程序中一般要修改SP的值,将堆栈设置到合适的位置,留出合适的堆栈空间。
假设某子程序执行过程中,ACC,PSW,DPTR的值可能发生变化,会影响到主程序的正确执行。在进入子程序后,为保护现场,可以使用如下程序段把ACC,PSW,DPTR的值压入堆栈保护起来。
PUSH ACC ;注意累加器A此处应写作ACC,使用直接寻址方式 PUSB PSW PUSH DPH PUSH DPL
假设上述程序段执行之前,SP的值为60H,程序执行后,SP的值变为64H。
当子程序执行完毕,返回主程序之前,可使用如下程序段恢复现场。
POP DPL POP DPH POP PSW POP ACC
这段程序执行完成后,SP的值恢复为60H,且ACC,PSW,DPTR均恢复为压入堆栈时的值。
9.数据交换指令
XCH A,Rn ;(A)↔(Rn) XCH A,direct ;(A)↔(direct) XCH A,@Ri ;(A)↔((Ri)) XCHD A,@Ri ;(A).3~0↔((Ri)).3~0
这组指令功能是两个操作数的内容相互交换。其中前三条指令的功能是使整个字节的内容交换,第四条指令的功能是使两个操作数的低半字节的内容交换,高半字节保持不变。
2.2.4 算术运算指令
算术运算指令共有24条,用到ADD,ADDC,SUBB,MUL,DIV,INC,DEC,DA 8个助记符,可直接实现单字节无符号数的加法、减法、乘法、除法、加1、减1等运算,借助标志位可实现有符号数和多字节数的算术运算,还可实现压缩BCD码的运算,见表2-12。
表2-12 算术运算类指令一览表
算术运算类指令的执行过程会对PSW中的标志位(进位标志Cy、溢出标志OV、辅助进位标志AC)产生影响,此外还有一些其他指令也会对这些标志位产生影响。影响标志位的指令如表2-13所示。
表2-13 影响标志位的指令
注:
1.“×”表示指令对该位有影响,可能置1,也可能清0;“0”表示指令对该位清0。
2.直接访问特殊功能寄存器PSW(地址0D0H)或各标志位的位地址的指令也会影响标志位。
1.不带进位的加法指令
ADD A,Rn ;A←(A)+(Rn) ADD A,direct ;A←(A)+(direct) ADD A,@Ri ;A←(A)+((Ri)) ADD A,#data ;A←(A)+data
这四条指令的功能是把第二操作数的内容和累加器A的内容相加,结果放入累加器A。加法指令会影响进位标志Cy、溢出标志OV和辅助进位标志AC,影响规则如下:
相加过程中如果D7位(最高位)有进位,则进位标志Cy置1,否则Cy清0;如果D3位有进位,则辅助进位标志AC置1,否则AC清0;如果D7位有进位而D6位没有进位,或者D6位有进位而D7位没有进位,则溢出标志OV置1,否则OV清0。
无符号数进行加法运算后,如果Cy=1,说明和数溢出(大于255);有符号数进行加法运算后,如果OV=1,说明和数溢出(超出了−128~+127的范围);如果AC=1,说明低半字节向高半字节有进位,AC标志用于BCD码加法运算。
例如,(A)=64H,(R0)=0A0H时,执行指令“ADD A,R0”的过程为:
计算过程中,D7位发生了进位输出,所以Cy置1;D6位和D7位同时发生了进位输出,所以OV清0;D3位没有发生进位,所以AC清0;运算完成后累计器A中有奇数个“1”,所以奇偶标志位P置1。
从运算结果看,作为无符号数运算时100+160=260,和数超过了255,所以Cy置1;作为有符号数运算时即100+(–96)=4,和数在–128~+127范围内,所以OV清0。实际上单片机并不知道参与运算的二进制数是无符号数、有符号数还是BCD码,单片机只是按照运算规则进行计算,运算的实际意义是由用户程序赋予的。
2.带进位的加法指令
ADDC A,Rn ;A←(A)+(Rn)+(Cy) ADDC A,direct ;A←(A)+(direct) +(Cy) ADDC A,@Ri ;A←(A)+((Ri)) +(Cy) ADDC A,#data ;A←(A)+data+(Cy)
这四条指令的功能是把第二操作数的内容和累加器A的内容相加,再和进位标志位Cy的值(0或1)相加,结果放入累加器A。带进位的加法指令会影响进位标志Cy、溢出标志OV、辅助进位标志AC,影响规则与不带进位的加法指令相同。
3.减法指令
SUBB A,Rn ;A←(A)-(Rn)-(Cy) SUBB A,direct ;A←(A)-(direct)-(Cy) SUBB A,@Ri ;A←(A)-((Ri))-(Cy) SUBB A,#data ;A←(A)-data-(Cy)
这四条指令的功能是从累加器A中减去第二操作数的内容,并减去进位标志位Cy的值(0或1),结果放入累加器A。这四条指令都是带借位的减法指令,MCS-51单片机没有不带借位的减法指令,若要进行不带借位的减法操作,需要事先把Cy清0。减法指令会影响进位标志Cy、溢出标志OV和辅助进位标志AC,影响规则如下:
减法过程中如果D7位(最高位)发生了借位,则进位标志Cy置1,否则Cy清0;如果D3位向D4位有借位,则辅助进位标志AC置1,否则AC清0;如果D7位有借位而D6位没有借位,或者D6位有借位而D7位没有借位,则溢出标志OV置1,否则OV清0。
无符号数进行减法运算后,如果Cy=1,说明发生了溢出(小数减去大数);有符号数进行减法运算后,如果OV=1,说明发生了溢出(超出了–128~+127的范围);如果AC=1,说明低半字节向高半字节有借位,AC标志用于BCD码运算。
例如,当(A)=64H,(R0)=0A8H,(Cy)=0时,执行指令“SUBB A,R0”的过程为:
计算过程中,D7位发生了借位,所以Cy置1;D6位和D7位发生了不同时借位,所以OV置1;D3位发生了借位,所以AC置1;运算完成后累计器A中有奇数个“1”,所以奇偶标志位P置1。
从运算结果看,作为无符号数运算时100–168=–68,差超过了0~255的范围,所以Cy置1;作为有符号数运算时即100–(–88)=188,差超出了–128~+127范围,所以OV置1。
4.增量(加1)指令
INC A ;A←(A)+1 INC Rn ;Rn←(Rn)+1 INC direct ;direct←(direct)+1 INC @Ri ;(Ri)←((Ri))+1 INC DPTR ;DPTR←(DPTR)+1
这组指令的功能是把操作数的内容加1。若指令执行前操作数的内容为0FFH,则加1后将发生溢出,操作数的内容变成00H,但不影响任何标志位。最后一条指令是对DPTR中的16位数进行加1操作,指令执行时,先对低8位数据DPL进行加1操作,如果发生了溢出则对高8位数据DPH进行加1操作,均不影响标志位。
5.减1指令
DEC A ;A←(A)-1 DEC Rn ;Rn←(Rn)-1 DEC direct ;direct←(direct)-1 DEC @Ri ;(Ri)←((Ri))-1
这组指令的功能是把操作数的内容减1。若指令执行前操作数的内容为00H,则减1后将发生溢出,操作数的内容变成0FFH,但不影响任何标志位。对数据指针DPTR只有加1操作指令,没有减1操作指令。
6.乘法指令
MUL AB ;BA←(A)×(B)
这条指令的功能是将累计器A的内容与寄存器B的内容相乘,乘积的低字节放在累加器A中,乘积的高字节放在累加器B中,如果乘积大于255,则溢出标志OV置1,否则OV清0。进位标志Cy总是被清0。
7.除法指令
DIV AB ;被除数(A) ÷ 除数(B) = 商(A) … 余数(B)
这条指令的功能是累计器A中的8位无符号数除以寄存器B中的8位无符号数,运算结果商的整数部分放在累加器A中,余数部分放在累加器B中。如果除数(寄存器B)为0,则溢出标志OV置1,且A与B中的内容为不确定;否则OV清0。进位标志Cy总是被清0。
8.十进制调整指令
DA A
这条指令总是放在ADD或ADDC指令之后运行,作用是对BCD码加法运算的结果进行十进制调整,使累加器A中的内容为2位合法的压缩型BCD码。
其执行过程可以用高级语言描述如下:
if [[(A3-0) > 9] or [(AC) = 1]] then (A3-0) = (A3-0) + 6 if [[(A7-4) > 9] or [(Cy) = 1]] then (A7-4) = (A7-4) + 6
执行该指令时,首先处理累加器A的低半字节,即判断A的低半字节是否大于9或AC是否为1,如果这两个条件有一个满足,则A的低4位进行加6操作,加6运算时如果发生了整字节的进位则置位进位标志Cy,但不会清零进位标志Cy;然后处理累加器A的高半字节,即判断A的高半字节是否大于9或Cy是否为1,如果这两个条件有一个满足,则高4位进行加6操作,加6运算时如果发生了整字节的进位则置位进位标志Cy,但不会清零进位标志Cy。
在整个执行过程中进位标志Cy都是只允许置1而不允许清0,利用这个特点单片机可以实现多字节的BCD码的加法。DA指令不影响溢出标志位OV。
2.2.5 逻辑运算及移位指令
逻辑运算及移位指令共25条,可分为逻辑与指令、逻辑或指令、逻辑异或指令、简单逻辑指令和移位指令等,用到的助记符有ANL,ORL,XRL,CLR,CPL,RR,RRC,RL,RLC和SWAP 10个,见表2-14。
表2-14 逻辑运算及移位指令一览表
1.逻辑与指令
ANL A,Rn ;A←(A)∧(Rn) ANL A,direct ;A←(A)∧(direct) ANL A,@Ri ;A←(A)∧((Ri)) ANL A,#data ;A←(A)∧data ANL direct,A ;direct←(direct)∧(A) ANL direct,#data ;direct←(direct)∧data
这组指令的功能是将两个操作数的内容按位进行逻辑“与”运算,运算结果放入目标操作数。
2.逻辑或指令
ORL A,Rn ;A←(A)∨(Rn) ORL A,direct ;A←(A)∨(direct) ORL A,@Ri ;A←(A)∨((Ri)) ORL A,#data ;A←(A)∨data ORL direct,A ;direct←(direct)∨(A) ORL direct,#data ;direct←(direct)∨data
这组指令的功能是将两个操作数的内容按位进行逻辑“或”运算,运算结果放入目标操作数。
3.逻辑异或指令
XRL A,Rn ;A←(A)⊕(Rn) XRL A,direct ;A←(A)⊕(direct) XRL A,@Ri ;A←(A)⊕((Ri)) XRL A,#data ;A←(A)⊕data XRL direct,A ;direct←(direct)⊕(A) XRL direct,#data ;direct←(direct)⊕data
这组指令的功能是将两个操作数的内容按位进行逻辑“异与”运算,运算结果放入目标操作数。
4.简单逻辑指令
这组指令的功能是对累加器A的内容进行简单逻辑运算。CLR A的功能是清0累加器A;CPL A的功能是对累加器A的内容按位取反。
5.移位指令
RL A ;(An+1)←(An),n=0~6;(A0)←(A7) RLC A ;(An+1)←(An),n=0~6;(Cy)←(A7);(A0)←(Cy) RR A ;(An)←(An+1),n=0~6;(A7)←(A0) RRC A ;(An)←(An+1),n=0~6;(Cy)←(A0);(A7)←(Cy) SWAP A ;(A7-4)↔(A3-0)
这组指令的功能是对累加器A的内容进行循环移位操作。
RL A的功能是将累计器A的内容向左环移1位,最高位移入最低位。
RLC A的功能是将累计器A的内容向左环移1位,最高位移入进位标志Cy,Cy的内容移入累加器的最低位。
RR A的功能是将累加器A的内容向右环移1位,最低位移入最高位。
RRC A的功能是将累计器A的内容向右环移1位,最低位移入进位标志Cy,Cy的内容移入累加器的最高位。
SWAP A的功能是交换累加器A的高半字节和低半字节。
2.2.6 控制转移指令
控制转移类指令共22条,主要包括子程序的调用和返回指令、无条件转移指令、有条件转移指令等,用到ACALL,LCALL,RET,RETI,AJMP,LJMP,SJMP,JMP,JZ,JNZ,JC,JNC,JB,JNB,JBC,CJNE,DJNZ,NOP共18个助记符,指令丰富、功能强大。合理使用这些指令可实现顺序、分支、循环等程序结构,完成复杂的软件功能,见表2-15。
在汇编语言程序设计时,可以给子程序入口指令加上标号,在调用子程序指令中用标号代替地址。自动汇编程序在把汇编语言源程序翻译为机器语言程序时会自动把标号替换为具体的入口地址。
表2-15 控制转移类指令一览表
1.调用子程序指令
ACALL addr11是2KB范围内的子程序调用指令。执行时先把PC的值加2获得下一条指令的首地址,把这个地址压入堆栈保护起来,作为子程序的返回地址。然后把PC的高5位和addr11连接起来形成16位的子程序入口地址送入PC,转去执行子程序。所调用的子程序入口地址必须与下一条指令的首字节地址处于同一个2KB的范围内,否则不能正确调用。这条指令和AJMP指令都是为了与之前的MCS-48系列单片机指令兼容而设置的。指令的执行不影响标志位。ACALL addr11指令的执行过程为:
PC ← (PC) + 2
SP ← (SP) + 1
(SP) ← (PC7-0)
SP ← (SP) + 1
(SP) ← (PC15-8)
PC10-0 ← addr11
LCALL addr16是64KB范围内的子程序调用指令。执行时先把PC的值加3获得下一条指令的首地址,把这个地址压入堆栈保护起来,作为子程序的返回地址。然后把子程序入口地址addr16送入PC,转去执行子程序。所调用的子程序可存放在程序存储器64KB空间的任意位置,指令的执行不影响标志位。LCALL addr16指令的执行过程为:
PC ← (PC) + 3 SP ← (SP) + 1 (SP) ← (PC7-0) SP ← (SP) + 1 (SP) ← (PC15-8) PC ← addr16
2.子程序返回指令
RET指令的功能是从堆栈中弹出子程序返回地址并装入PC,返回主程序。执行后SP的值会减2,不影响标志位。RET指令的执行过程为:
PC15-8 ← ((SP)) SP ← (SP)–1 PC7-0 ← ((SP)) SP ← (SP) –1
3.中断子程序返回指令
RETI指令的功能和RET指令基本相同,唯一的区别是RETI指令还要清除MCS-51单片机内部的中断服务程序执行标志。
4.无条件转移指令
AJMP addr11 ;PC10-0←addr11
LJMP addr16 ;PC←addr16
SJMP rel ;PC←(PC)+2+rel
JMP @A+DPTR ;PC←(A)+(DPTR)
这组指令的功能是无条件地转移到操作码和操作数给出的目标地址处,这组指令不影响堆栈,也不影响标志位。
AJMP addr11称为绝对转移指令,执行时首先令PC=PC+2,指向下一条指令的首地址,然后把PC的高5位和指令给出的11位的地址连接起来,形成16位的目标地址,把这个目标地址装入PC,实现程序的转移。AJMP指令的转移范围是下一条指令的首地址所处的2KB范围内。
LJMP addr16称为长转移指令,执行时首先令PC=PC+3,指向下一条指令的首地址,然后把指令给出的16位目标地址装入PC,实现程序的转移。LJMP指令的转移范围是全部64KB地址空间。
SJMP rel称为短转移指令或相对转移指令,执行时首先令PC=PC+2,指向下一条指令的首地址,然后把PC的内容和8位有符号的偏移量相加得到目标地址,把这个目标地址装入PC,实现程序的转移。SJMP指令的转移目标在相对下一条指令的首地址偏移–128~+127B的范围内。
JMP @A+DPTR称为基址加变址的转移指令或散转指令,执行时首先令PC=PC+1,指向下一条指令的首地址,然后把A中的8位无符号数和DPTR的内容相加得到目标地址,把这个目标地址装入PC,实现程序的转移。由于DPTR的16位数值可任意设置,JMP指令可转移到64KB范围内任何位置。这条指令根据A和DPTR的内容可转移到不同的目标地址,可实现类似C语言中SWITCH语句的功能。
5.条件转移指令
JZ rel ;如果(A)=0则转移,PC←(PC)+2+rel JNZ rel ;如果(A)≠0则转移,PC←(PC)+2+rel JC rel ;如果(Cy)=1则转移,PC←(PC)+2+rel JNC rel ;如果(Cy)≠1则转移,PC←(PC)+2+rel JB bit,rel ;如果(bit)=1则转移,PC←(PC)+3+rel JNB bit,rel ;如果(bit)≠1则转移,PC←(PC)+3+rel JBC bit,rel ;如果(bit)=1则转移,PC←(PC)+3+rel,且bit←0
这组指令和下面的CJNE、DJNZ指令都属于有条件转移指令。有条件转移指令执行时首先判断条件是否满足,如果条件满足就进行转移,否则顺序执行下面的指令。转移的目标地址采样相对寻址的方式给出,rel的内容作为有符号数,取值范围为–128~+127。转移的目标地址在以下一条指令的首地址为中心的256个字节的范围内,即(PC)+N+rel,N为本条转移指令的存储字节数。
6.比较不相等转移指令
CJNE A,direct,rel ;若(A)≠(direct)则PC←(PC)+3+rel,若(A)< (direct)则C←1 CJNE A,#data,rel ;若(A)≠data则PC←(PC)+3+rel,若(A)< data则C←1 CJNE Rn,#data,rel ;若(Rn)≠data则PC←(PC)+3+rel,若(Rn)< data则C←1 CJNE @Ri,#data,rel ;若((Ri))≠data则PC←(PC)+3+rel,若((Ri))<data则C←1
这组指令属于有条件转移指令。指令执行时首先比较前两个操作数是否相等,如果不相等则转移到rel给出的目标地址,否则顺序执行下一条指令。当第一个操作数小于第二个操作数时Cy置1,否则Cy清0。CJNE指令不影响其他标志位,也不改变各个操作数的值。
7.减1不为0转移指令
DJNZ Rn,rel ;Rn←(Rn)-1;如果(Rn)≠0则转移,PC←(PC)+2+rel DJNZ direct,rel ;direct←(direct)-1;如果(direct)≠0则转移,PC←(PC)+3+rel
这组指令属于有条件转移指令。指令执行时首先把源操作数的内容减1,结果回送到源操作数,然后判断该操作数是否为0,如果不为0则转移到rel给出的目标地址,否则顺序执行下一条指令。DJNZ指令不影响标志位,但是会改变第一个操作数的值。
8.空操作指令
NOP空操作指令占用一个机器周期,但不执行任何实际操作。NOP指令可用于实现一个机器周期的延时。
2.2.7 位操作指令
MCS-8051单片机内含一个完整的位处理器(也叫布尔处理器),程序状态字PSW中的进位标志位Cy就是这个位处理器的位累加器。在内部RAM中有128个可位寻址位,SFR区最多可支持128个可位寻址位,四个并行I/O接口的每一个引脚都是可位寻址的。MCS-51单片机的位处理器指令集除了根据位变量的条件转移指令之外,还包括数据传送、置位、清零、取反、或运算、与运算等指令,基于字节的处理器中很少具备这么完善的布尔量处理指令。位操作指令见表2-16。
表2-16 位操作指令一览表
1.位修改指令
这组指令的作用是对位操作数清0、置1或取反,不影响其他标志位。
2.位逻辑与指令
这组指令的功能是位累加器C和直接寻址位的值进行逻辑“与”运算,运算结果放入位累加器C,不影响其他标志位。第二操作数前的斜杠“/”表示将该位的内容取反后参与运算,但不改变该操作数的值。
3.位逻辑或指令
这组指令的功能是位累加器C和直接寻址位的值进行逻辑“或”运算,运算结果放入位累加器C,不影响其他标志位。第二操作数前的斜杠“/”表示将该位的内容取反后参与运算,但不改变该操作数的值。
4.位传送指令
MOV C,bit ;C←(bit) MOV bit,C ;bit←(C)
这组指令的功能是在位累加器C和直接寻址位之间进行布尔量的传送,不影响其他标志位。
习题
2-1 MCS-51单片机有多少个引脚?这些引脚可分为哪几类?
2-2 MCS-51单片机的、、ALE、RST引脚的作用是什么?
2-3 80C51单片机的内部RAM区可分为哪几个部分?
2-4 MCS-51单片机的寻址方式有几种?每种寻址方式的寻址范围是什么?
2-5 什么是时钟周期、机器周期、指令周期?当单片机时钟频率为12MHz时,机器周期是多少,执行一条MUL AB指令需要多长时间?
2-6 定时器/计数器有几种工作方式?分别是什么?
2-7 当单片机时钟频率为12MHz,定时器/计数器用作定时器时,能否设定1μs、1ms、1s的定时长度,如何设定?
2-8 定时器/计数器用作计数器时,对外部计数脉冲的频率有何限制?
2-9 串行口有几种工作方式?串行中断标志位TI和RI如何清0,如何置1?
2-10 PSW中的Cy和OV有什么作用?下列程序段执行后,Cy和OV的值是什么?
MOV A,#69H ADD A,#8CH
2-11 执行下列程序段后,内部RAM 61H、62H、30H、31H、DPTR和SP中的内容是多少?
MOV SP,#60H MOV 30H,#56H MOV 31H,#78H PUSH 30H PUSH 31H POP DPL POP DPH
2-12 设(A)=85H,(R1)=23H,(23H)=36H,下列程序段执行后,A的内容是多少?
ANL A,#23H ORL 23H,A CPL A XOL A,@R1 SWAP A
2-13 下列程序执行后,R0、R1、R2的内容是多少?
MOV R0,#10 MOV R1,#01H MOV A,R1 LOOP:RL A JB ACC.7 LB1 DJNZ R0,LOOP LB1: MOV R2,A
2-14 试编写汇编语言程序,完成以下功能:
(1)R0的内容传送到R1;
(2)片内RAM 40H单元的内容送R0;
(3)片内RAM 40H单元的内容送片内RAM 50H单元;
(4)片外RAM 40H单元的内容送片内RAM 50H单元;
(5)片外RAM 2000H单元的内容送片内RAM 50H单元;
(6)ROM 2000H单元的内容送R0;
(7)ROM 2000H单元的内容送片外RAM 1000H单元。