第三章MSC-51单片机的指令系统3.1指令系统概述一、机器码指令与汇编语言指令机器码指令:汇编语言指令:二、指令格式汇编语言格式为:[标号:]操作码助记符[目的操作数,][源操作数][;注释]单字节指令双字节指令三字节指令操作码24H操作数22HINCAADDA,#22HMOV5EH,4FH操作码04H操作码85H源操作数4FH目的操作数5EH图3-1机器码指令格式3.2寻址方式一、寄存器寻址二、直接寻址三、立即寻址四、寄存器间接寻址五、变址寻址六、相对寻址七、位寻址3.3MSC-51单片机的指令系统按照指令的功能,可以把MSC-51的111条指令分成五类:l数据传送类指令(29条)l算术运算类指令(24条)l逻辑操作类指令(24条)l控制转移类指令(17条)l位操作类指令(17条)80H下一条指令ALU54Hrel=54H2000H2001H2002H2056H操作码PC当前值2002H修正后转移目标地址(PC)=2056H∶∶图3-2相对寻址过程第四章MCS-51单片机的应用程序设计过程A过程B是否入口出口条件满足?P2入口出口P1P3过程是否入口出口条件满足?(a)顺序结构(b)分支结构(c)循环结构图4-1基本程序结构4.1运算程序一、多字节数加法1.多字节无符号数加法CLRCMOVR0,#40H;指向加数最低位MOVR1,#5OH;指向另一加数最低位MOVR2,#04H;字节数作计数初值LOOP1:MOVA,@R0;取被加数ADDCA,@R1;两数相加,带进位MOV@R0,AINCR0;修改地址INCR1DJNZR2,LOOPl;未加完转LOOP1JNCLOOP2;无进位转LOOP2MOV@R0,#01HLOOP2:DECR0RET2.多字节有符号数加法MOVA,R0;复制保存地址指针MOVR2,AMOVA,R3MOVR7,ACLRCLOOP1:MOVA,@R0ADDCA,@R1;相加MOV@R0,AINCR0INCR1;地址指针加1DJNZR7,LOOP1JBOV,ERR;若溢出,转溢出处理DECR0MOVA,@R0JNBE7H,LOOP2SETB07H;和值为负,置位标志LOOP2:MOVA,R2;恢复地址指针MOVR0,ARET┇ERR:┇;溢出处理RET正负标志清零YN加完?开始复制保存地址指针清C正负标志置位溢出处理指针加1作加法,存和数正?溢出?YN恢复地址指针返回SDADD:CLR07H;标志位清零图4-3多字节有符号数加法程序流程图二、多字节数减法MOVR0,#40H;指向被减数最低位MOVR1,#5OH;指向减数最低位MOVR2,#04H;字节数CLRCLOOP1:MOVA,@R0SUBBA,@R1;完成一个字节的减法运算MOV@R0,AINCR0INCR1DJNZR2,LOOP1RET三、多字节十进制数(BCD码)加法清标志位YN加完?开始最高字节置1取被加数有进位?YN恢复地址指针返回指针加1求和调整图4-4BCD码多字节加法程序流程图BCDADD:MOV20H,R0MOV23H,R3CLRCLOOP0:MOVA,@R0;取被加数ADDCA,@R1;两数相加DAA;十进制调整MOV@R0,AINCR0;指针加1INCR1DJNZR3,LOOP0;作完加法否MOVR2.#23HJNCRETURN;有无进位MOV@R0,#01HINCR3RETURN:MOVR0,#20HRET四、多字节数乘法ZHENFA:MOVA,R0MOVB,R1MULAB;(R1)*(R0)MOVR3,A;积的低位送到R3MOVR4,B;积的高位送到R4MOVA,R0MOVB,R2MULAB;(R2)*(R0)ADDA,R4;(R1)*(R0)的高位加(R2)*(R0)的低位MOVR4,A;结果送R4,进位在CY中MOVA,BADDCA,#OOH;(R2)*(R0)的高位加低位来的进位MOVR5,A;结果送R5RET五、多字节数除法DV:MOVR7,#08H;设计数初值DVl:CLRCMOVA,R5RLCAMOVR5,AMOVA,R6RLCA;将(R6)、(R5)左移一位MOV07H,C;将移出的一位送07H位保存CLRC图4-5除法程序流程图SUBBA,R2;余数(高位)减除数JBO7H,GOU;若标志位为1,说明够减除法次数→R7YN标志位=1?开始清进位,(R6)(R5)左移一位进位位=0?YN恢复余数返回余数高位-除数移出的位→标志位商上1保存余数(R7)-1=0?YNJNCGOU;无借位也说明够减ADDA,R2;否则,恢复余数AJMPDV2GOU:INCR5;商上1DV2:MOVR6,A;保存余数(高位)DJNZR7,DVlRET一、数据的拼拆4.2数据的拼拆和转换例4-7设在30H和31H单元中各有一个8位数据:(30H)=x7x6x5x4x3x2x1x0(3lH)=y7y6y5y4y3y2y1y0现在要从30H单元中取出低5位,并从31H单元中取出低3位完成拼装,拼装结果送40H单元保存,并且规定:(40H)=y2y1y0x4x3x2x1x0解:利用逻辑指令ANL、ORL来完成数据的拼拆,程序清单如下:MOV4OH,3OH;将x7~x0传送到40H单元ANL4OH,#000111llB;将高3位屏蔽掉MOVA,31H;将y7~y0传送到累加器中SWAPA;将A的内容左移4次RLA;y2~y0移到高3位ANLA,#111000OOB;将低5位屏蔽掉ORL4OH,A;完成拼装任务二、数据的转换1.ASCII码与二进制数的互相转换例4-10编程实现十六进制数表示的ASC1I代码转换成4位二进制数(1位十六进制数)。解:对于这种转换,只要注意到下述关系便不难编写出转换程序:“字符0”~“字符9”的ASCII码值为“30H”~“39H”,它们与30H之差恰好为“00H”~“09H”,结果均<0AH。“字符A”~“字符F”的ASCII码值为“41H”~“46H”,它们各自减去37H后恰好为“0AH”~“0FH”,结果0AH。根据这个关系可以编出转换程序如下,程序以R1作为入口和出口。ASCHIN:MOVA,R1;取操作数CLRC;清进位标志位CSUBBA,#30H;ASCII码减去30H,实现0-9的转换MOVR1,A;暂存结果SUBBA,#0AH;结果是否9?JCLOOP;若≤9则转换正确XCHA,R1SUBBA,#07H;若9则减37HMOVR1,ALOOP:RET2.BCD码与二进制数的转换取高字节BCD数开始调用子程序返回结果×100保存结果两结果相加取低字节BCD数调用子程序高位BCD数开始乘以10返回保存结果加低位BCD数图4-6BCD码(十进制)转换成二进制数程序流程图程序清单如下:MAIN:MOVA,R5MOVR2,A;给子程序入口参数ACALLBCDBIN;调用子程序MOVB,#64HMULABMOVR6,AXCHA,BMOVR5,AMOVA,R4MOVR2,AACALLBCDBIN;调用子程序ADDA,R6MOVR4,AMOVA,R5ADDCA,#00HMOVR5,ARET子程序如下:BCDBIN:MOVA,R2ANLA,#0F0H;取高位BCD码,屏蔽低4位SWAPAMOVB,#0AHMULABMOVR3,AMOVA,R2ANLA,#0FHADDA,R3;加低位BCD码MOVR2,ARET4.3查表程序使用MOVCA,@A+DPTR指令来查表,程序清单如下:MOVDPTR,#BS;子程序入口地址表首址RLA;键码值乘以2MOVR2,A;暂存AMOVCA,@A+DPTR;取得入口地址低位PUSHA;进栈暂存INCAMOVCA,@A+DPTR;取得入口地址高位MOVDPH,APOPDPLCLRAJMP@A+DPTR;转向键处理子程序BS:DBRK0L;处理子程序入口地址表DBRK0HDBRK1LDBRK1HDBRK2LDBRK2H┇┇4.4散转程序一、采用转移指令表的散转程序例4-17编出要求根据R3的内容转向各个操作程序的程序。即当(R3)=0,转向OPRO(R3)=1,转向OPRl…(R3)=n,转向OPRn解:程序清单如下:MOVA,R3RLA;分支序号值乘2MOVDPTR,#BRTABL;转移指令表首址JMP@A+DPTR;转向形成的散转地址BRTABL:AJMPOPR0;转移指令表AJMPOPR1…AJMPOPRn二、采用地址偏移量表的散转程序例4-19编出能按R6的内容转向5个操作程序的程序。其对应关系如下:OPRD0:操作程序0OPRD1:操作程序1OPRD2:操作程序2OPRD3:操作程序3OPRD4:操作程序4解:程序清单如下:MOVA,R6MOVDPTR,#TAB3;指向地址偏移量表首址MOVCA,@A+DPTR;散转点入口地址在A中JMP@A+DPTR;转向相应的操作程序入口TAB3:DBOPRDO-TAB3;地址偏移量表DBOPRDl-TAB3DBOPRD2-TAB3DBOPRD3-TAB3DBOPRD4-TAB3三、采用转向地址表的散转程序例4-20编程:要求根据R6的内容转向相应的操作程序中去。设备操作程序的转向地址分别为OPRD0,OPRDl,…OPRDn。解:程序清单如下:MOVDPTR,#BRTABL;指向转向地址表MOVA,R6ADDA,R6;(A)←(R6)*2JNCNAND;INCDPH;(R6)*2的进位加到DPHNAND:MOVR3,A;暂存变址值MOVCA,@A+DPTR;取转向地址高8位XCHA,R3INCAMOVCA,@A+DPTR;取转向地址低8位MOVDPL,A;转向地址在DPTR中MOVDPH,R3CLRAJMP@A+DPTR;转向相应的操作程序BRTABL:DWOPRDO;转向地址表DWOPRD1┆DWOPRDn四、采用“RET”指令的散转程序例4-21编出能根据R6的内容转向各个操作程序的程序。设该操作程序的转向地址分别为OPRD0,OPRDl,…OPRDn。解:程序清单如下:MOVDPTR,#TAB3;指向转移地址表MOVA,R6ADDA,R6JNCNANDINCDPHNAND:MOVR7,AMOVCA,@A+DPTR;取转向地址高8位XCHA,R7INCAMOVCA,@A+DPTR;取转向地址低8位PUSHA;转向地址入栈MOVA,R7PUSHARET;转向操作程序TAB3:DWOPRD0;转向地址表DWOPRDl┇DWOPRDn4.5I/O端口控制程序例4-22试编出能模拟图4-9中电路的程序。GF+DEVCC8031P1.0P1.1P1.2P1.3K0K1K3DEF(a)8031的接线(b)被模拟电路ORG0200HDBIT00HEBIT01HGBIT02HLOOP1:ORLP1,#08H;准备P1.3输入LOOP2:MOVC,P1.3;检测K3状态JCLOOP2;若未准备好(K3断),则LOOP2ORLP1,#03H;若准备好,则准备输入P1.0和P1.1状态MOVC,P1.0;输入K0状态MOVD,C;送入DMOVC,P1.1;输入K1状态MOVE,C;送入EANLC,D;D∧E送CMOVG,C;送入GMOVC,EORLC,D;D∨E送CANLC,/G;(D∨E)∧(D∧E)MOVP1.2,C;输出结果SJMPLOOP1;准备下次模拟END4.6子程序调用时的参数传递方法一、通过寄存器或片内RAM传递参数例4-23利用通过寄存器或片内RAM传递参数这种方法编出调用SUBRT子程序的主程序。解:应该是:MAIN:MOVR0,#30H;传送RAM数据区的起始地址MOVR7,#0AH;传送RAM数据区的长度ACALLSUBRT;调用清零子程序SJMP$;结束SUBRT:MOVA,#00H;清零子程序LOOP:MOV@R0,AINCR0DJNZR7,LOOPRET二、通过堆栈传递参数例4-25在HEX单元存有两个十六进制数,试编程分别把它们转换成ASCII码存入ASC和ASC+1单元。解:本题子程序采用查表方法完成一个