第四章:MCS-51程序设计计算机与通信工程学院李耀明计算机与通信工程学院一、汇编语言概述1、指令系统语句格式[标号]:操作码[操作数];[注释]指令编码长短:单字节,双字节,三字节执行周期:一个机器周期占12个振荡周期,单周期指令,双周期,4周期寻址方式:指令中所规定的寻找操作地址的方式立即、直接、寄存器、寄存器间接寻址、基址加变址、相对寻址、位寻址指令分类:数据传送、算术、逻辑、位操作、控制转移2、程序设计的步骤(1)分析问题,编制说明要解决问题的程序框图。(2)确定数据结构、算法、工作单元、变量设定(与高级语言不同)(3)根据所用的指令系统,按照已编制的程序框图用汇编语言编制出源程序。(4)将编制出的程序在计算机上调试,直至实现预定的功能。计算机与通信工程学院二、程序设计分类1、顺序程序:执行时按顺序一条条地执行指令2、分支程序:当程序不再顺序执行,而向一个方向或多个方向转移时,叫分支程序。3、循环程序:对于需要反复的程序段,常采用循环办法,以缩短程序。4、子程序及其调用程序主程序使用子程序时,用调用指令(ACALL),子程序最后放一条RET指令。计算机与通信工程学院三、程序设计准则结构清晰:便于分析层次分明:便于阅读语言简洁:便于分析易于理解:便于阅读计算机与通信工程学院4.1简单程序设计简单程序又称顺序程序。计算机是按指令在存储器中存放的先后次序来顺序执行程序的。除非用特殊指令让它跳转,不然它会在PC控制下执行。计算机与通信工程学院例4-1两个8位无符号数相加ORG0000HAJMPBEGINORG0030HBEGIN:MOV40H,#01HMOV41H,#02HLOOP:MOVR0,#40HMOVA,@R0INCR0ADDA,@R0INCR0MOV@R0,AJMPLOOPEND开始R0←40HA←(R0)A送(42H)(40H)+(41H)和送A返回图4-1例1流程图例:将加数和被加数分别送入40H、41H单元,加完后和送入42H单元计算机与通信工程学院例4-2将两个半字节数合并成一个单字节数程序ORG0000HAJMPstartORG0030HSTART:MOVsp,#60HMOV40h,#01hMOV41h,#02hloop:MOVR1,#40HMOVA,@R1ANLA,#0FH;取第一个半字节SWAPAINCR1XCHA,@R1;取第二字节ANLA,#0FH;取第二个半字节ORLA,@R1;拼字INCR1MOV@R1,A;存放结果AJMP$END执行完后如何不改变内存和寄存器的值?开始(40H)内容送A,屏蔽高位,交换高低位A←(R0)A与(R1)或后送(42H)取(41H)内容,屏蔽高位,送A返回图4-2例2流程图计算机与通信工程学院4.2分支程序设计在处理实际事务中,只用简单程序设计的方法是不够的。因为大部分程序总包含有判断、比较等情况。根据判断、比较的结果转向不同的分支计算机与通信工程学院例4-3:两个无符号数比较大小设两个连续外部RAM单元ST1和ST2中存放不带符号的二进制数,找出其中的大数存入ST3单元中。ST1EQU8040HORG0000HJMPSTARTORG0030HSTART:MOVDPTR,#ST1MOVA,#12HMOVX@DPTR,AINCDPTRMOVA,#34HMOVX@DPTR,ALOOP:CLRC;进位位清零MOVDPTR,#ST1;设数据指针MOVXA,@DPTR;取第一数MOVR2,A;暂存R2INCDPTRMOVXA,@DPTR;取第二个数SUBBA,R2;两数比较JNCBIG1XCHA,R2;第一数大BIG0:INCDPTRMOVX@DPTR,A;存大数SJMP$BIG1:MOVXA,@DPTR;第二数大SJMPBIG0END开始设置指针DPTR初始值取第一个数存入R2取第二个数后者减前者进位标志是否为0?存后者结束存前者图5-3例4流程计算机与通信工程学院例4-4:编制计算符号函数y=SGN(x)的程序AREEQU8040HBUFEQU8060HORG0000HJMPSTARTORG0030HSTART:MOVDPTR,#AREMOVA,#0F0HMOVX@DPTR,ALOOP:MOVDPTR,#ARE;进位位清零MOVXA,@DPTR;取第一数JZSULJBACC.7,NEGMOVA,#01HSUL:MOVDPTR,#BUFMOVX@DPTR,AJMPLOOPNEG:MOVA,#0FFHSJMPSULEND计算机与通信工程学院4.3循环程序设计简单程序,每条指令只执行一次分支程序则根据条件的不同,会跳过一些指令,执行另一些指令。它们的特点是,每一条指令至多执行一次。在处理实际事务时,有时会遇到多次重复处理的问题,用循环程序的方法来解决就比较合适。循环程序中的某些指令可以反复执行多次。采用循环程序,使程序缩短,节省存储单元。重复次数越多,循环程序的优越性就越明显。程序的执行时间并不节省。由于要有循环准备、结束判断等指令,速度要比简单程序稍慢些。计算机与通信工程学院循环程序组成循环程序一般由五部分组成:1、初始化部分:为循环程序做准备。如:设置循环次数计数器的初值,地址指针置初值,为循环变量赋初值等。2、处理部分:为反复执行的程序段,是循环程序的实体。3、修改部分:每执行一次循环体后,对指针作一次修改,使指针指向下一数据所在位置,为进入下一轮处理作准备。4、控制部分:根据循环次数计数器的状态或循环条件,检查循环是否能继续进行,若循环次数到或循环条件不满足,应控制退出循环,否则继续循环。通常2、3、4部分又称为循环体。5、结束部分:分析及存放执行结果。计算机与通信工程学院循环程序的结构循环程序的结构一般有两种形式:先进入处理部分,再控制循环。至少执行一次循环体。先控制循环,后进入处理部分。即先根据判断结果,控制循环的执行与否,有时可以不进入循环体就退出循环程序。计算机与通信工程学院主要语句寻址方式寄存器间接寻址MOVA,@RiMOVXA,@DPTRMOVXA,@Ri基址寄存器+变址寄存器间接寻址MOVCA,@A+DPTRMOVCA,@A+PC循环计数DJNZRn,relDJNEA,direct,relJZ(JNZ,JC,JNC,JB,JNB)rel计算机与通信工程学院例4-5工作单元清零将40H为起点的8个单元清“0”ORG0000HCLEAR:CLRA;A清0MOVR0,#40H;确定清0单元起始地址MOVR7,#08;确定要清除的单元个数LOOP:MOV@R0,A;清单元INCR0;指向下一个单元DJNZR7,LOOP;控制循环END计算机与通信工程学院例4-5工作单元清零例如:设有50个外部RAM单元要清“0”,即为循环次数存放在R2寄存器中,其首址存放在DPTR中,设为2000HORG0000HMOVDPTR,#2000HCLEAR:CLRAMOVR2,#32H;置计数值LOOP:MOVX@DPTR,AINCDPTR;修改地址指针DJNZR2,LOOP;控制循环END计算机与通信工程学院例4-5工作单元清零写成通用子程序形式:CLEAR:CLRALOOP:MOVX@DPTR,AINCDPTR;修改地址指针DJNZR2,LOOP;控制循环RET完整调用ORG0000HMOVDPTR,#2000HMOVR2,#50ACALLCLEARSJMP$CLEAR:CLRALOOP:MOVX@DPTR,AINCDPTR;修改地址指针DJNZR2,LOOP;控制循环RETEND计算机与通信工程学院例4-6多个单字节数据求和已知有n个单字节数据,依次存放在内部RAM40H单元开始的连续单元中。要求把计算结果存入R2,R3中(高位存R2,低位存R3)。程序如下:ORG8000HSAD:MOVR0,#40H;设数据指针MOVR5,#NUM;计数值0AH→R5SAD1:MOVR2,#0;和的高8位清零MOVR3,#0;和的低8位清零LOOP:MOVA,R3;取加数ADDA,@R0MOVR3,A;存和的低8位JNCLOP1;无进位,直接计算高8位INCR2;有进位,和的高8位+1LOP1:INCR0;指向下一数据地址DJNZR5,LOOPRETNUMEQU0AHEND上述程序中,用R0作间址寄存器,每作一次加法,R0加1,数据指针指向下一数据地址,R5为循环次数计数器,控制循环的次数。计算机与通信工程学院例4-7测试字符串长度设有一串字符依次存放在从50H单元开始的连续单元中,该字符串以回车符(0DH)为结束标志,测得的字符串长度存入R2中。测字符串长度程序是将该字符串中的每一个字符依次与回车符相比,若比较不相等,则统计字符串长度的计数器加1。继续比较,若比较相等,则表示该字符串结束,计数器中的值就是字符串的长度。程序如下:ORG0000HCONT:MOVR2,#00H;初始长度设置MOVR0,#50H;数据指针R0置初值NEXT:CJNE@R0,#0DH,LOOP1RETLOOP1:INCR0INCR2SJMPNEXTEND待测字符以ASCII码形式存放在RAM中,回车符的ASCII码为0DH,程序中用一条CJNE@R0,#0DH,LOOP指令实现字符比较及控制循环的任务,当循环结束时,R2的内容为字符串长度计算机与通信工程学院例4-910秒延时程序延时程序与MCS-51执行指令的时间有关,如果使用6MHz晶振,一个机器周期为2μs,计算出执行一条指令以至一个循环所需要的时间,给出相应的循环次数,便能达到延时的目的。程序如下:DEL:MOVR5,#100DEL0:MOVR6,#200DEL1:MOVR7,#248DEL2:DJNZR7,DEL2;248*2+4DJNZR6,DEL1;(248*2+4)*200+4DJNZR5,DEL0;(248*2+4)*200+4)*100+4RET上例延时程序实际延时为10.000406秒。它是一个三重循环程序,利用程序嵌套的方法对时间实行延迟是程序设计中常用的方法。使用多重循环程序时,必须注意以下几点:(1)循环嵌套,必须层次分明,不允许产生内外层循环交叉。(2)外循环可以一层层向内循环进入,结束时由里往外一层层退出。(3)内循环体可以直接转入外循环体,实现一个循环由多个条件控制的循环结构方式。计算机与通信工程学院例4-10冒泡程序MOVR6,#CNTDECR6LOOPA:MOVR0,#30HMOVA,R6MOVR7,ACLR20H.0NEXT:MOVA,@R0INCR0CLRCSUBBA,@R0JCNXCHMOVA,@R0DECR0XCHA,@R0INCR0MOV@R0,ASETB20H.0CNTEQU07HORG0000HAJMPSTARTORG0030HSTART:MOVDPTR,#LISTMOVR0,#30HMOVR7,#CNTLOOPD:CLRAMOVCA,@A+DPTRMOV@R0,AINCDPTRINCR0DJNZR7,LOOPDNXCH:DJNZR7,NEXTJNB20H.0,OVERDJNZR6,LOOPAOVER:AJMP$LIST:DB70H,13H,3H,90H,27H,32H,11Hend计算机与通信工程学院例4-13无符号数双字节乘法R2R3×R6R7--------------------------------R3×R7R2×