第4章汇编语言程序设计及编程实例1.ppt_第1页
第4章汇编语言程序设计及编程实例1.ppt_第2页
第4章汇编语言程序设计及编程实例1.ppt_第3页
第4章汇编语言程序设计及编程实例1.ppt_第4页
第4章汇编语言程序设计及编程实例1.ppt_第5页
已阅读5页,还剩95页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章汇编语言程序设计及知识,4.1编程的步骤、方法和技巧4.2汇编语言源程序的编辑和汇编,4.3汇编语言程序的基本结构,4.1编程的步骤、方法和技巧,4.1.1编程的步骤4.1.2编程的方法和技巧,4.1.1编程的步骤,一、分析问题二、确定算法三、画程序流程图四、编写程序,一、分析问题,对需要解决的问题进行分析,以求对问题由正确的理解。如,解决问题的任务是什么?工作过程?现有的条件,已知数据,对运算的精度和速度方面的要求?设计的硬件结构是否方便编程?,二、确定算法,算法是如何将实际问题转化成程序模块来处理。在编程以前,先要对几种不同的算法进行分析、比较,找出最适宜的算法,三、画程序流程图,程序流程图是使用各种图形、符号、有向线段等来说明程序设计过程的一种直观的表示。流程图步骤分得越细致,编写程序是也越方便。画流程图是程序结构设计是采用的一种重要手段。一个系统软件有总的流程图(主程序框图)和局部的流程图。流程图常采用的图形和符号。,椭圆框,或桶形框,:表示程序的开始或结束。,矩形框,:表示要进行的工作。,菱形框,:表示要判断的事情,菱形框内的表达式表示要判断的内容。,圆圈,:表示连接点,指向线,:表示程序的流向,四、编写程序,用89C51汇编语言编写的源程序行(一条语句)包括四个部分,也叫四个字段:标号:操作码操作数;注释每个字段之间要用分隔符分隔,而每个字段内部不能使用分隔符。可以用作分隔符的符号:空格“”、冒号“:”、逗号“,”、分号“;”等。例:LOOP:MOVA,#00H;立即数00HA,标号,标号是用户定义的符号地址。一条指令的标号是该条指令的符号名字,标号的值是汇编这条指令时指令的地址。标号由以英文字母开始的18个字母或数字组成,以冒号“:”结尾。标号可以由赋值伪指令赋值,如果没有赋值,汇编程序把存放该指令目标码第一字节的存储单元的地址赋给该标号,所以,标号又叫指令标号。,操作码,操作码是必不可少的。它用一组字母符号表示指令的操作码。在89C51中,由89C51的指令助记符组成。,操作数,汇编语言指令可能要求或不要求操作数,所以这一字段可能有也可能没有。若有两个操作数,操作数之间用逗号“,”分开。操作数包括的内容有:(1)工作寄存器:由PSW.3和PSW.4规定的当前工作寄存器区中的R0R7。(2)特殊功能寄存器:21个SFR的名字。(3)标号名:赋值标号由汇编指令EQU等赋值的标号;指令标号指令标号指示的指令的第一字节地址是该标号的值。(4)常数:可用二进制(B)、十进制、十六进制(H),若常数以字符开头,前面加0。(5)$:用来表示程序计数器的当前值。(6)表达式:汇编时,计算出表达式的值填入目标码。,注释,注释部分不是汇编语言的功能部分,只是用语增加程序的可读性。良好的注释是汇编语言程序编写中的重要组成部分。,4.1.2编程的方法和技巧,一、模块化的程序设计方法二、编程技巧,一、模块化的程序设计方法,1、程序功能模块化的优点2、划分模块的原则,1、程序功能模块化的优点,单个模块结构的程序功能单一,易于编写、调试和修改。便于分工,从而可使多个程序员同时进行程序的编写和调试工作,加快软件研制进度。程序可读性好,便于功能扩充和版本升级。对程序的修改可局部进行,其它部分可以保持不变。对于使用频繁的子程序可以建立子程序库,便于多个模块调用。,2、划分模块的原则,每个模块应具有独立的功能,能产生一个明确的结果,即单模块的功能高内聚性。模块之间的控制耦合应尽量简单,数据耦合应尽量少,即模块间的低耦合性。控制耦合是指模块进入和退出的条件及方式,数据耦合是指模块间的信息交换方式、交换量的多少及交换频繁程度。模块长度适中。20条100条的范围较合适。,二、编程技巧,1、尽量采用循环结构和子程序。2、尽量少用无条件转移指令。3、对于通用的子程序,考虑到其通用性,除了用于存放子程序入口参数的寄存器外,子程序中用到的其他寄存器的内容应压入堆栈(返回前再弹出),即保护现场。4、在中断处理程序中,除了要保护处理程序中用到的寄存器外,还要保护标志寄存器。5、用累加器传递入口参数或返回参数比较方便,在子程序中,一般不必把累加器内容压入堆栈。,4.2汇编语言源程序的编辑和汇编,4.2.1源程序编辑4.2.2源程序的汇编4.2.3伪指令,4.2.1源程序编辑,在微型计算机上,借助编辑软件,编写或修改汇编语言源程序。如行编辑或屏幕编辑软件。,4.2.2源程序的汇编,汇编:将汇编语言源程序转换为机器码表示的目标程序的过程。对单片机有:一、手工汇编二、机器汇编三、反汇编,一、手工汇编,通过手工方式查指令编码表,逐个把助记符指令“翻译”成机器码,然后把得到的机器码程序键入单片机,进行调试和运行。手工汇编的缺点:1、偏移量的计算容易出错2、程序的修改会引起后面指令地址的变化,转移指令的偏移量也要重新计算。,二、机器汇编,机器汇编是在计算机上使用交叉汇编程序进行源程序的汇编。汇编工作由机器自动完成,最后得到以机器码表示的目标程序。,三、反汇编,将二进制机器语言程序翻译成汇编语言程序的过程称反汇编。汇编和反汇编的过程如图4-3所示。,源程序(汇编语言),目标码(机器语言),汇编(汇编程序),反汇编(汇编程序),图4-3汇编和反汇编过程,4.2.3伪指令,伪指令不是真正的指令,无对应的机器码,在汇编时不产生目标程序,只是用来对汇编过程进行某种控制。,ORG汇编起始命令,格式:ORG16位地址功能:规定该伪指令后面程序的汇编地址,即汇编后生成目标程序存放的起始地址。例如:ORG2000HSTART:MOVA,#64H规定了START的地址是2000H,又规定了汇编后的第一条指令码从2000H开始存放。,END汇编结束指令,格式:END功能:通知汇编程序结束汇编。在END之后所有的汇编指令均不予以处理。,EQU赋值命令,格式:字符名称EQU项(数或汇编符号)功能:把“项”赋给“字符名称”。注意:字符名称不等于标号(其后没有冒号);其中的项,可以是数,也可以是汇编符号。EQU赋值过的符号名可以用作数据、代码地址、位地址或一个立即数。可以是8位的,也可以是16位的。例如:,EQU赋值命令,例1:AAEQUR1MOVA,AA;AA代表工作寄存器R1例2:A10EQU10DELYEQU07EBHMOVA,A10;A10作为片内的一个直接地址LCALLDELY;DELY作为一个16位子程序的入口地址,DATA数据地址赋值命令,格式:字符名称DATA表达式功能:与EQU类似,但有以下差别:1、EQU定义的字符名必须先定义后使用,而DATA定义的字符名可以后定义先使用。2、用EQU伪指令可以把一个汇编符号赋给一个名字,而DATA只能把数据赋给字符名。3、DATA语句可以把一个表达式的值赋给字符名称,其中的表达式应是可求值的。DATA伪指令在程序中用来定义数据地址,DB定义字节命令,格式:DB(项或项表)功能:通知汇编程序从当前ROM地址开始,保留一个字或字节串的存储单元,并存入DB后的数据。注意:项或项表可以是一个字节、用逗号隔开的字节串或括在单引号中的ASCII字符串。例如:,DB定义字节命令,ORG2000HDB0A3HLIST:DB26H,03HSTR:DBABC经汇编后(2000H)=A3H,(2001H)=26H,(2002H)=03H,(2003H)=41H,(2004H)=42H,(2005H)=43H,(41H,42H,43H分别为A,B,C的ASCII码);(见书P12),DW定义字命令,格式:DW16位数据项或项表功能:把DW后的16位数据项或项表从当前地址连续存放。每项数值为16位二进制数,高8位先放,低8位后存放。DW用于定义一个地址表。例如:,DW定义字命令,ORG1500HTABLE:DW7234H,8AH,10H经汇编后(1500H)=72H,(1501H)=34H,(1502H)=00H,(1503H)=8AH,(1504H)=00H,(1505H)=10H,,DS定义存储空间命令,格式:DS表达式功能:在汇编时,从指定地址开始保留DS之后表达式的值所规定的存储单元以备后用。例如:ORG1000HDS08HDB30H,8AH汇编后,从1000H保留8个单元,然后从1008H按DB命令给内存赋值,即(1008H)=30H(1009H)=8AH,BIT位地址符号命令,格式:字符名BIT位地址功能:把BIT后的位地址值赋给字符名。其中字符名不是标号,其后没有冒号,但字符名是必须的。例如:A1BITP1.0A2BIT02H汇编后,P1口第0位的位地址90H就赋给了A1,而A2的值则为02H。,4.3汇编语言程序的基本结构,一、顺序程序二、分支程序三、循环程序,一、顺序程序,顺序程序是最简单的程序结构,即顺序结构。程序按顺序一条一条地执行指令。,一简单程序设计举例,例1:拆字。将片内RAM20H单元的内容拆成两段,每段四位。并将它们分别存入21H与22H单元中。程序如下:,Back,例如:(20H)=56H,程序运行后(21H)=06H,(22H)=05H,例2:双字节无符号数加法。设被加数存放在内部RAM的51H、50H单元,加数存放在内部RAM的61H、60H单元,相加的结果存放在内部RAM的51H、50H单元,进位存放在位寻址区的00H位中。,程序:,MOVR0,50H;被加数的低字节地址;2B,2usMOVR1,60H;加数的低字节地址;2B,2usMOVA,R0;取被加数低字节;1B,1usADDA,R1;加上加数低字节;1B,1usMOVR0,A;保存低字节相加结果;1B,1us,这两条指令能否用其他指令代替?,INCR0;指向被加数高字节;1B,1usINCR1;指向加数高字节;1B,1usMOVA,R0;取被加数高字节;1B,1usADDCA,R1;加数高字节(带进位加)1B,1usMOVR0,A;存高字节相加结果;1B,1usMOV00H,C;保存进位;2B,2us,这里为什么采用带进位的加法,而前面采用不带进位的加法?,例3:有一变量存放在片内RAM的20H单元,其取值范围为:00H05H。要求编制一段程序,根据变量值求其平方值,并存入片内RAM的21H单元。,程序1:MOVA,20HMOVB,AMULABMOV21H,A,程序如下:ORG1000HSTART:MOVDPTR,#2000HMOVA,20HMOVCA,A+DPTRMOV21H,ASJMP$ORG2000HTABLE:DB00,01,04,09,16,25END,二、分支程序,程序分支是通过条件转移指令实现的,即根据条件对程序的执行进行判断、满足条件则进行程序转移,不满足条件就顺序执行程序。分支程序又分为单分支和多分支结构。多分支程序是首先把分支程序按序号排列,然后按序号值进行转移。,二、分支程序,在MCS-51指令系统中,通过条件判断实现单分支程序转移的指令有:JZ、JNZ、CJNE、DJNZ等。此外还有以位状态作为条件进行程序分支的指令,如JC、JNC、JB、JNB、JBC等。使用这些指令可以完成0、1、正、负,以及相等、不相等作为各种条件判断依据的程序转移。,(1)CJNEA,#10,L1;(A)=10顺序执行LABLE1:L1:JNCLABLE1;(A)10跳转到LABLE1,一、单分支程序例1编写程序实现(1)(A)=10时则程序转至标号LABLE1处执行。(2)(A)10时则程序转至标号LABLE2处执行(3)(A)源字节内容,则CY位清零,否则置1,判“1”跳转,若CY1,跳转,(2)SUBBA,#10JNCLABLE2;(A)10跳转LABLE2:(3)CJNEA,#10,L1;(A)=10顺序执行LABLE3:L1:JCLABLE3;(A)0,且现A=00H,即跳转至LP;若CY=1,则则原A0,且现A=80H00H,顺序执行,三、多分支程序,例1128种分支转移程序。功能:根据入口条件转移到128个目的地址。入口:(R3)=转移目的地址的序号00H7FH。出口:转移到相应子程序入口。,说明:此程序要求128个转移目的地址(ROUT00ROUT7FH)必须驻留在与绝对转移指令AJMP相同的一个2KB存储区内。RL指令对变址部分乘以2,因为每条AJMP指令占两个字节。注:即A=00H、02H、04H每一个数据的偏移地址是2的整数倍,三、循环程序,在程序运行时,有时需要连续重复执行某段程序,可以使用循环程序。其结构包括四部分:1、置循环初值2、循环体(循环工作部分)3、修改控制变量4、循环控制部分其组织方式如P74图4-4所示。,1、置循环初值,对于循环程序中所使用的工作单元,在循环开始时应置初值。例如,工作寄存器设置计数初值,累加器A清0,以及设置地址指针、长度等。,2、循环体(循环工作部分),重复执行的程序段部分,分为循环工作部分和循环控制部分。循环控制部分每循环一次,检查结束条件,当满足条件时,就停止循环,往下继续执行其他程序,3、修改控制变量,在循环程序中,不许给出循环结束条件。常见的是计数循环,当循环了一定的次数后,就停止循环。在单片机中,一般用一个工作寄存器Rn作为计数器,对该计数器赋初值作为循环次数。每循环一次,计数器的值减1,即修改循环控制变量,当计数器的置件为0时,就停止循环。,4、循环控制部分,根据循环结束条件,判断是否结束循环。89C51可采用DJNZ指令来自动修改控制变量并能结束循环。,置初值,循环体,循环修改,循环控制,退出循环,未完,完,(a),置初值,循环体,循环修改,循环控制,退出循环,未完,完,(b),图4-4循环组织方式流程图,一、先执行后判断,例350ms延时程序。若晶振频率为12MHz,则一个机器周期为1s。执行一条DJNZ指令需要2个机器周期,即2s。采用循环计数法实现延时,循环次数可以通过计算获得,并选择先执行后判断的循环结构。DELY:MOVR6,#50;1usDELY1:DJNZR6,DELY1;2us*50=100usRET;2us本段程序延时时间为:1+100+2=103us单循环最长延时时间为:1+256*2+2=515us50ms延时程序段如下页:,DEL:MOVR7,#200;1sDEL1:MOVR6,#123;1sNOP;1sDEL2:DJNZR6,DEL2;2s,计(2123)sDJNZR7,DEL1;2s,RET;2s共计1+(212322)200+2s,即50.003ms双重循环最长延时时间为:1+(225522)255+2s,即131.070ms,DEL:MOVR7,#200;1sDEL1:MOVR6,#123;1sNOP;1sDEL2:DJNZR6,DEL2;2s,计(2123)sDJNZR7,DEL1;2s,RET;2s共计1+(212322)200+2s,即50.003ms双重循环最长延时时间为:1+(225522)255+2s,即131.070ms,练习1:设计一个延时时间为5ms的延时子程序。,二、先判断后执行例4将内部RAM中起始地址为data的数据串传送到外部RAM中起始地址为buffer的存储区域内,直到发现$字符停止传送。由于循环次数事先不知道,但循环条件可以测试到。所以,采用先判断后执行的结构比较适宜。程序段如下:,MOVR0,#data,MOVDPTR,#buffer,LOOP0:MOVA,R0,SJMPLOOP2;是$字符,转其它程序,CJNEA,#24H,LOOP1;判断是否为$字符,LOOP1:MOVXDPTR,A;不是$字符,执行传送,INCR0,INCDPTR,SJMPLOOP0;传送下一数据,LOOP2:,$的ASC码,练习2:统计以$字符为结尾的字符串长度并送NUM单元,设字符串放在内部RAM中起始地址为data的存储区域内。,MOVR0,#data,MOVR1,#0,LOOP0:MOVA,R0,SJMPLOOP2;是$字符,转结束,CJNEA,#24H,LOOP1;判断是否为$字符,LOOP1:INCR1;不是$字符,取下一个字符,INCR0,SJMPLOOP0;下一字符,LOOP2:MOVNUM,R1;字符串长度送NUM单元,四代码转换程序设计举例,例5:R1中存有一个BCD码,编一子程序将其转换为ASCII码,存入片外RAM1000H单元中去。,一、BCD码与ASCII码之间的转换,为什么要将累加器A的内容+30H?,思考题:当有多个BCD码时,如何将其转换为ASCII码,并存入到指定的单元中去?,例6:用查表法编一子程序,将40H单元中的BCD码转换成ASCII码。入口:待转换数在(40H)出口:转换后的数(40H),例7若将30H单元BCD码转换成ASCII码,利用SUB1子程序。,例8片外RAM2000H单元中有一BCD码,编一子程序将其转换成ASCII码。,Back,二、BCD码与二进制数之间的转换在计算机中,十进制数要用BCD码来表示。通常,用四位二进制数表示一位BCD码,用1个字节表示2位BCD码(称为压缩型BCD码)。,实验:编程将A中的二进制数拆为三个BCD码,并存入Result开始的三个单元如(A)=01111011B=123D=7BH,则执行程序结果应为(30H)=1,(31H)=2,(32H)=3,十进制数,三、十六进制数与ASCII码间的转换十六进制数与ASCII码的对应关系如表所示。,当十六进制数在09之间时,其对应的ASCII码值为该十六进制数加30H;当十六进制数在AF之间时,其对应的ASCII码值为该十六进制数加37H。,为什么此处+37H而不是41H或其他值?,例9将1位十六进制数转换成相应的ASCII码。设十六进制数存放在R0中,转换后的ASCII码存放于R2中。,实现程序如下,HASC:MOVA,R0;取4位二进制数,ANLA,#0FH;屏蔽掉高4位,PUSHACC;4位二进制数入栈,ADDA,#06H;用半进位位的状态判断该数在09还是AF之间,POPACC;弹出原4位二进制数,JNBPSW.6,LOOP;AC位为0,跳转至LOOP,ADDA,#37H;AC为1,该数在AF之间,加37H,LOOP:ADDA,#30H;该数在09之间,加30H,LOOP1:MOVR2,A;ASCII码存于R2,RET,SJMPLOOP1,此处为什么要用堆栈操作指令PUSH和POP?不用行不行?,思考题:除加#06H判断外,还可以用什么方法判断?,实现程序如下,HASC:MOVA,R0;取4位二进制数,ANLA,#0FH;屏蔽掉高4位,PUSHACC;4位二进制数入栈,CLRC;清进(借)位位,SUBBA,#0AH;用借位位的状态判断该数在09还是AF之间,POPACC;弹出原4位二进制数,JCLOOP;借位位为1,跳转至LOOP,ADDA,#07H;借位位为0,该数在AF之间,加37H,LOOP:ADDA,#30H;该数在09之间,加30H,MOVR2,A;ASCII码存于R2,RET,五子程序设计,Back,一、子程序的调用在实际应用中,经常会遇到一些带有通用性的问题,例如:数值转换、数值计算等,在一个程序中可能要使用多次。这时可以将其设计成通用的子程序供随时调用。子程序的结构与一般的程序并无多大区别,它的主要特点是,在执行过程中需要由其它程序来调用,执行完后又需要把执行流程返回到调用该子程序的主程序。子程序调用时要注意两点:一是现场的保护和恢复;二是主程序与子程序的参数传递。,Back,二、现场保护与恢复在子程序执行过程中常常要用到单片机的一些通用单元,如工作寄存器R0R7、累加器A、数据指针DPTR,以及有关标志和状态等。而这些单元中的内容在调用结束后的主程序中仍有用,所以需要进行保护,称为现场保护。在执行完子程序,返回继续执行主程序前恢复其原内容,称为现场恢复。保护与恢复的方法有以下两种:在主程序中实现;在子程序中实现。,Back,1、在主程序中实现示例如下:PUSHPSW;保护现场PUSHACCPUSHBMOVPSW,#10H;换当前工作寄存器组LCALLaddr16;子程序调用POPB;恢复现场POPACCPOPPSW其特点是结构灵活。,2、在子程序中实现示例如下:SUB1:PUSHPSW;保护现场PUSHACCPUSHBMOVPSW,#10H;换当前工作寄存器组为2组POPB;恢复现场POPACCPOPPSWRET其特点是程序规范、清晰。注意,无论哪种方法保护与恢复的顺序要对应。,三、参数传递由于子程序是主程序的一部分,所以,在程序的执行时必然要发生数据上的联系。在调用子程序时,主程序应通过某种方式把有关参数(即子程序的入口参数)传给子程序,当子程序执行完毕后,又需要通过某种方式把有关参数(即子程序的出口参数)传给主程序。在80C51单片机中,传递参数的方法有三种:1、利用累加器或寄存器在这种方式中,要把预传递的参数存放在累加器A或工作寄存器R0R7中。即在主程序调用子程序时,应事先把子程序需要的数据送入累加器A或指定的工作寄存器中,当子程序执行时,可以从指定的单元中取得数据,执行运算。反之,子程序也可以用同样的方法把结果传送给主程序。,例10编写程序,实现c=a2+b2。设a,b,c分别存于内部RAM的30H,31H,32H三个单元中。,程序段如下:START:MOVA,30H;取aACALLSQR;调用查平方表MOVR1,A;a2暂存于R1中MOVA,31H;取bACALLSQR;调用查平方表ADDA,R1;a2+b2存于A中MOV32H,A;存结果SJMP$SQR:MOVDPTR,#TAB;子程序MOVCA,A+DPTR;查表RETTAB:DB0,1,4,9,16,25,36DB49,64,81,100,121,2、利用存储器当传送的数据量比较大时,可以利用存储器实现参数的传递。在这

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论