(精品)第4章 80C51单片机汇编语言程序设计

上传人:沈*** 文档编号:248480841 上传时间:2024-10-24 格式:PPT 页数:64 大小:787.51KB
返回 下载 相关 举报
(精品)第4章 80C51单片机汇编语言程序设计_第1页
第1页 / 共64页
(精品)第4章 80C51单片机汇编语言程序设计_第2页
第2页 / 共64页
(精品)第4章 80C51单片机汇编语言程序设计_第3页
第3页 / 共64页
点击查看更多>>
资源描述
,课程:单片机技术 教材:单片机基础,第,4,章,MCS-51,汇编语言程序设计,教学基本要求,:,(,1,)、了解,MCS-51,汇编语言程序设计的特点;,(,2,)、熟悉,MCS-51,汇编语言伪指令的功能及用法;,(,3,)、掌握顺序、分支、循环程序的设计方法,;,(,4,)、掌握,KEIL,软件的使用方法。,教学重点,:,(,1,)、,KEIL,软件的使用方法,;,(,2,)、分支、循环程序的设计方法;,(,3,)、定时、查表程序的设计方法;,教学难点,:,(,1,)、,KEIL,软件调试程序的方法,;,(,2,)、利用,JMP A+DPTR,指令实现程序多分支;,(,3,)、查表程序的设计方法;,(,4,)、子程序结构与堆栈的关系。,4.1,单片机程序程序设计语言概述,4.1.1,机器语言和,汇编语言,4.1.2,单片机使用的高级语言,(,1,),BASIC,语言,(,2,),C,语言,(,3,),PL/M,语言,4.1.3 80C51,单片机汇编语言的语句格式,汇编语言程序设计,必须注意如下特点:,(,1,),设计人员必须详细了解单片机的硬件结构,以便在程序设计中熟练使用;,(,2,)必须熟悉汇编语言指令的功能和用法;,(,3,)在程序设计前,必须分析设计任务,确定所用算法,确定程序结构,确定数据的类型、数据的结构,必须对数据的存放、寄存器和工作单元的使用以及所用硬件资源等作出具体安排;,(,4,)根据分析,画出程序设计流程图;,(,5,)根据程序设计流程图编写程序。,4.2,汇编语言程序的基本结构形式,单片机,汇编语言程序设计的基本结构形式一般分为以下,4,种形式,即顺序结构、分支结构、循环结构和子程序结构。,4.2.1,顺序程序结构,顺序程序是,最简单的程序结构,在,顺序,程序中,,,既无分支,循环,也,不调用,子程序,程序执行时一条一条,地,按顺序执行指令,例:假定三字节无符号数相加,其中一个加数在内部,RAM,的,50H,、,51H,和,52H,单元中,另一个加数在内部,RAM,的,53H,、,54H,和,55H,单元中,要求把相加之和存放在,50H,、,51H,和,52H,单元中,进位存放在位寻址区的,00H,位中。,解,:(,1,)分析任务:求两数之和,(,2,)算法:加法运算(,ADD,或,ADDC,),(,3,)程序结构,:,顺序或循环结构,(,4,)数据类型:三字节、二进制、无符号数,(,5,),数据结构:升序或降序排列,(,6,),RAM,单元安排,: (内部,RAM,字节单元、位地址空间,),(,7,)采用寄存器间接寻址方式(,R0,、,R1,),加数(,N1,),高字节(,8,位),中字节(,8,位),低字节(,8,位),加数(,N2,),高字节(,8,位),中字节(,8,位),低字节(,8,位),加数(,N1,),加数(,N2,),和(,N3,),52H,单元,低字节(,8,位),55H,单元,低字节(,8,位),52H,单元,低字节(,8,位),51H,单元,中字节(,8,位),54H,单元,中字节(,8,位),51H,单元,中字节(,8,位),50H,单元,高字节(,8,位),52H,单元,高字节(,8,位),50H,单元,高字节(,8,位),00H位,进位位,(,8,)程序设计流程框图;,(,9,)程序清单;,ORG 1000H,MOV RO,,,#52H,;,加数,N1,的低字节地址送地址指针,R0,MOV R1,,,#55H,;,加数,N2,的低字节地址送地址指针,R1,MOV A,,,R0,; 取,N1,的低字节,ADD A,,,R1,;,N1,、,N2,低字节相加,MOV R0,,,A,;,保存,N1,、,N2,低字节和,DEC R0,;,修改加数,N1,的,地址指针内容,DEC R1,;,修改加数,N2,的地址指针内容,MOV A,,,R0,; 取,N1,的中间字节,ADDC A,,,R1,;,N1,、,N2,中间字节带低字节和进位相加,MOV R0,,,A,;,保存,N1,、,N2,中间字节和,DEC R0,;,修改加数,N1,的地址指针内容,DEC R1,;,修改加数,N2,的地址指针内容,MOV A,,,R0,;,取,N1,的高字节,ADDC A,,,R1,;,N1,、,N2,高字节带中间字节和进位相加,MOV R0,,,A,;,保存,N1,、,N2,高字节和,MOV 00H,,,C,;,高字节和的,进位送,00H,位保存,END,思考题:,1,)上述程序中,如果只采用,ADDC,指令,应如何修改程序?,2,)如果,N1,、,N2,,,N3,均为,十进制数,应如何修改程序?,3,)如果加数,N1,在内部,RAM,50H,、,51H,和,52H,单元中,,而,加数,N2,与,和,N3,均,在外部,RAM00,53H,、,0054H,和,0055H,单元中,,其它条件不变,,应如何修改程序?,4,)如果,N1,、,N2,,,N3,均存放在外部,RAM,单元,应如何修改程序?,例:设内部,RAM 40H,,,41H,单元中分别存放,8,位二进制数,,现分别,取,这,两个单元中的半,个,字节,合并成一个,新,字节存放在,42H,单元,中,。,要求如下:,42H,单元,新字节的低半字节取自,40H,单元的低半字节,而高半字节取自,41H,单元的低半字节。,解,:(,1,)分析任务:拆字、合字,(,2,)算法:逻辑运算,(,3,)程序结构:顺序,(,4,)数据类型:单字节、二进制、无符号数,(,5,)数据结构:升序或降序排列,(,6,)程序设计流程框图;,(,7,)程序清单;,ORG 2000H,S,TART: MOV R1,,,#40H,;,初始化数据指针,R1,的内容,MOV A,,,R1,;,取,40H,单元内容送,A,ANL A,,,#0FH,;,保留,40H,单元内容低,4,位,INC R1,;,修改数据指针,R1,的内容,XCH A,,,R1,;,(A),与,R1,内容互换,ANL A,,,#0FH,;,保留,41H,单元内容低四位,SWAP A,;,41H,单元内容高低半字节互换,ORL A,,,R1,;,合字生成新字节,INC R1,;,修改数据指针,R1,的内容,MOV R1,,,A,;,新字节送,42H,单元保存,END,作业题:,上例中其它条件不变,要求如下:,42H,单元,新字节的低半字节取自,40H,单元的低半字节,而高半字节取自,41H,单元的高半字节。,(,1,)单分支程序,单分支程序,是通过条件转移指令实现的,即根据条件对程序的执行进行判断,满足条件则进行程序转移,不满足条件程序就顺序执行。,在,MCS-51,指令系统中,可利用,JZ,,,JNZ,,,CJNE,,,DJNZ,,,JC,,,JNC,,,JB,,,JNB,,,JBC,等指令,完成为,0,、,为,1,、,为正,、,为负以及相等,、,不相等等各种条件判断。,例:两个,8,位无符号二进制数比较大小。,假,设,在外部,RAM,中有,ST1,、,ST2,和,ST3,共,3,个连续单元(单元地址从小到大,),,其,中,ST1,、,ST2,单元中,存放,着,两个,8,位,无符号二进制数,N1,,,N2,,,要求,找出其中,的,大数,并,存,入,ST3,单元,中,。,4.2.2,分支程序结构,解,:(,1,)分析任务:比较两个数的大小,(,2,)算法:算术运算、控制转移,(,3,)程序结构:单分支,(,4,)数据类型:单字节、二进制、无符号数,(,5,)数据结构:单元地址升序排列,(,6,),RAM,单元安排,:外部,RAM,单元,(,7,)采用寄存器间接寻址方式(,R0,、,R1,或,DPTR,),(,8,),程序设计流程框图,;,(,9,),程序清单,;,思考题(补充作业题):,上例中,如果采用,CJNE A,,,direct,,,rel,指令,应如何修改程序?,返回,ORG 8000H,START: CLR C,;,进位清,0,MOV DPTR,,,#ST1,;,设数据指针,MOVX A,,,DPTR,;,A,(,ST1,),取,N1,MOV R2,,,A,;,暂存,N1,INC DPTR,;,DPTR ST2,(,指向,N2,单元),MOVX A,,,DPTR,; 取,N2,存于,A,中,SUBB A,,,R2,;,N1,,,N2,比较(,N2-N1,,,差在,A,中),JNC BIG1,;,N2N1,,转,BIG1,,,N2,N1,,,顺序执行,XCH A,,,R2,;,N1,,,N2,互换,,A N1,SJMP BIG0,BIG1: MOVX A,,,DPTR,;,A N2,BIGO: INC DPTR,;,DPTR ST3,(,指向,N3,单元),MOVX DPTR,,,A,;,ST3 ,大数,END,返回,(,2,)多分支程序,假设多分支程序中,分支序号的最大值为,n,,,则多分支转移结构如图所示:,MCS-51,指令系统,没有,多分支,转移,指令,无法使用,单,条指令完成多分支转移,。要实现多分支转移,,可采用以下几种方法:,假设分支序号值保存在累加器,A,中,则可使用,CJNE A,,,#data,,,rel,指令,其分支流程如图所示:,(,a,),使用多条,CJNE,指令,通过逐次比较,实现分支程序转移,例:,已知,:,127,X,-128,,求,Y,。,设,X,,,Y,分别,存,放在外部,RAM 1000H,和,2000H,单元中。,解,:(,1,)分析任务:解方程,(,2,)算法:控制转移,(,3,)程序结构:多分支,(,4,)数据类型:单字节、二进制、有符号数,(,5,),RAM,单元安排,:外部,RAM,单元,(,6,)采用寄存器间接寻址方式(,R0,、,R1,或,DPTR,),(,7,),程序设计流程框图,(,8,),程序清单,;,思考题(补充作业题):,上例中,如果采用,CJNE,指令,应如何修改程序?,返回,ARE EQU 1000H,;,BUF EQU 2000H,;,ORG 1000H,START,:,MOV DPTR,,,#ARE,;,数据,X,的地址送数据指针,DPTR,MOVX A,,,DPTR,;,A,取,数据,X,JZ SUL,;,X,0,转,SUL,JB ACC.7,,,NEG,;,X,0,转,NEG,,,否则,,X,0,MOV A,,,#01H,;,SJMP SUL,;,NEG: MOV A,,,#0FFH,;,(0FFH,为,-1,补码,),SUL: MOV DPTR,,,#BUF,;,数据,Y,的地址送数据指针,DPTR,MOVX DPTR,,,A,;,保存,Y,值,END,返回,首先,在程序中建立一个转移指令表,在表格中存放转移指令,然后,通过查转移指令表的方式实现多分支程序转移。,这种方法主要利用散转指令,JMP A+DPTR,,,此指令采用变址寻址方式,操作过程:(,PC,)(,A,),+,(,DPTR,),,CPU,根据,PC,的内容来实现多分支程序转移。,DPTR,中送转移指令表的表首地址(常用转移指令表的名称标号代替),而,A,中送转移指令表中存放的转移指令的序号(常常从第,0,条开始)。,例如,有多个分支程序,如要通过,AJMP,转移指令进行转移,则应把这些转移指令按序写入转移指令表中,并设置一个序号指针(例如,R3,),,序号往往从,0,开始,然后可使用以下查表程序实现程序转移。,(,b,),使用查,转移指令,表,的,方法实现多分支程序转移,MOV A,,,R3,;,分支程序序号送,A,RL A,;,分支程序序号乘,2,MOV DPTR,,,#BRTAB,;,BRTAB,为转移指令表名称标号,,JMP A+DPTR,;,也为转移指令表首地址,BRTAB,:,AJMP ROUT0,;,分支程序,0,的转移指令,AJMP ROUT1,;,分支程序,1,的转移指令,AJMP ROUT2,;,AJMP ROUT127,;,分支程序,127,的转移指令,ROUT0,:,;,分支程序,0,ROUT1:,;,ROUT127:,;,分支程序,127,由于,AJMP,指令是二字节指令,因此,程序中通过,RL A,指令将分支序号乘,2,。转移指令表中最多只能安排,128,条分支转移指令,如需多于,128,条,则必须另行修改程序。,由于,AJMP,指令转移范围是,2KB,,,因此,分支程序应安排在以,JMP A+DPTR,指令为中心的,2KB,范围之内,否则会出错。,如果转移指令表中的转移指令是,LJMP,指令,则分支程序可安排在,64KB ROM,空间的任何地方。但转移指令表中的转移指令的条数最多为,85,条(,LJMP,指令是三字节指令),上述程序应作相应的修改。,MOV A,,,R3,;,MOV B,,,#03H,;,MUL AB,;,MOV DPTR,,,#BRTAB,;,BRTAB,为转移指令表名称标号,,JMP A+DPTR,;,也为转移指令表首地址,BRTAB,:,LJMP ROUT0,;,分支程序,0,的转移指令,LJMP ROUT1,;,分支程序,1,的转移指令,LJMP ROUT2,;,LJMP ROUT85,;,分支程序,85,的转移指令,ROUT0,:,;,分支程序,0,ROUT1:,;,ROUT85,:,;,分支程序,85,返回,4.2.3,循环程序结构,MCS-51,汇编语言指令系统没有专用的循环指令,但可以使用条件转移指令通过条件判断来控制循环是继续还是结束。,循环程序一般由四个主要部分组成,: ,(,1,)初始化部分:为循环程序做准备,如规定循环次数、给各变量和地址指针预置初值。 ,(,2,)处理部分,:,为反复执行的程序段,是循环程序的实体, 也是循环程序的主体。 ,(,3,)循环控制部分,:,其作用是修改循环变量和控制变量,并判断循环是否结束,直到符合结束条件时,跳出循环为止。,(,4,)结束部分,:,这部分主要是对循环程序的结果进行分析、处理和存放。,单循环程序一般有以下两种典型结构:,双重循环程序的结构:,在应用系统程序设计时,有时经常需要将数据存储器中各部分地址单元作为工作单元,以存放程序执行的中间值或执行结果,因此,在使用这些工作单元之前,必须将工作单元清零。工作单元清零可用循环程序完成。,例:假设在内部,RAM,区,开辟,96,个工作单元,工作单元首地址为,20H,,,则工作单元清零程序子程序如下,:,ORG 1000H,CLR0,:,MOV R0,,,#20H,;,循环初始化部分,MOV R7,,,#96,;,CLR A,LOOP,:,MOV R0,,,A,;,循环体部分,INC R0,;,修改变量,DJNZ R7,,,LOOP,;,循环控制部分,RET,END,思考题(补充作业题):如采用,CJNE,指令,应如何修改程序?,例:两个三字节二进制无符号数相加,被加数放在内部,RAM 20H,22H,单元(低字节存放在低地址单元,高字节存放在高地址单元,即低位在前,高位在后),加数放在,2AH,2CH,单元,和放在,20H,22H,单元,最高位如有进位,则放在,23H,单元中。,解:数据类型(二、十进制数,有、无符号数);数据结构(升、降序排列),被加数(,N1,),高字节(,8,位),中字节(,8,位),低字节(,8,位),加数(,N2,),高字节(,8,位),中字节(,8,位),低字节(,8,位),被加数(,N1,),加数(,N2,),和(,N3,),20H,单元,低字节(,8,位),2AH,单元,低字节(,8,位),20H,单元,低字节(,8,位),21H,单元,中字节(,8,位),2BH,单元,中字节(,8,位),21H,单元,中字节(,8,位),22H,单元,高字节(,8,位),2CH,单元,高字节(,8,位),22H,单元,高字节(,8,位),23H,单元,进位位,被加数,N1,高字节(,8,位) 中字节(,8,位) 低字节(,8,位),加数,N2,高字节(,8,位) 中字节(,8,位) 低字节(,8,位),+,)进位位(,CY,),进位位(,CY,),进位位(,CY,),和,N3,进位 高字节(,8,位) 中字节(,8,位) 低字节(,8,位),程序流程框图,程序清单,思考题:统计正数、负数、零的个数。,ORG 0030H,ADDDUO,:,MOV R0,,,#20H,;,循环初始化部分,MOV R1,,,#2AH,;,MOV R7,,,#03H,;,循环次数,CLR C,;,LOOP,:,MOV A,,,R0,;,循环体部分,ADDC A,,,R1,;,MOV R0,,,A,;,INC R0,;,修改指针变量,INC R1,;,DJNZ R7,,,LOOP,;,循环控制部分,CLR A,;,循环结束处理部分,ADDC A,,,#00H,;,MOV R0,,,A,;,RET,;,END,返回,返回,例:把内部,RAM,中起始地址为,DATA,的数据串传送到外部,RAM,以,BUFFER,为首地址的区域,直到发现“,$”,字符的,ASC,码为止,同时规定数据串最大长度为,32,个字节。,解,:(,1,)分析任务:数据传送;(,2,)算法:比较、控制转移,(,3,)程序结构:分支、循环(,4,)数据类型:多字节字符串,(,5,),RAM,单元安排,:内部,RAM,单元、,外部,RAM,单元,(,6,)采用寄存器间接寻址方式(,R0,、,R1,或,DPTR,),(,7,)程序流程框图;,ORG 0030H,DATACS,:,MOV R0,,,#DATA,;,DATA,数据区首地址,MOV DPTR,,,#BUFFER,;,BUFFER,数据区首地址,MOV R1,,,#20H,;,最大数据串长,LOOP,:,MOV A,,,R0,;,取数据,SUBB A,,,#24H,;,判是否为“,$”,字符,JZ LOOP1,;,是“,$”,字符,转结束,MOVX DPTR,,,A,;,数据传送,INC R0,;,INC DPTR,;,DJNZ R1,,,LOOP,;,循环控制,LOOP1,:,RET,;,结束,END,4.3 80C51,单片机,汇编语言程序设计举例,4.3.2,定时程序,在单片机的控制应用中,常有定时的需要,如定时中断、定时检测和定时扫描等。定时功能除可以使用纯硬件电路、可编程定时,/,计数器实现外,还可以使用软件程序(定时程序)完成。,定时程序是典型的循环程序,它是通过执行一个具有固定延迟时间的循环体来实现定时的。,(,1,)单循环定时程序,MOV R5,,,#TIME,;,LOOP: NOP,;,NOP,;,DJNZ R5,,,LOOP,;,假设,单片机晶振频,率,f,osc,=6MHz,,,则一个机器周期为,2s,,,NOP,、,DJNZ,指令分别是单、双机器周期指令。定时程序的总延迟时间是循环程序段延时时间的整数倍,由于,R5,是,8,位寄存器,因此,这个定时程序的最长定时时间为:,256,(,2,8,),8=2048,(,s,),(,2,),较长时间的定时程序,(多重循环定时子程序),TIME,:,MOV R5,,,#TTME1,;,LOOP,:,MOV R4,,,#TEME2,;,LOOP1,:,NOP,;,NOP,;,DJNZ R4,,,LOOP1,;,DJNZ R5,,,LOOP2,;,RET,;,这个定时子程序的最长定时时间为:,256,(,2,8,),4+2+1256,(,2,8,),2+4=525828,(,s,),(,3,),调整定时时间,在定时程序中可通过在循环程序段中增减指令的方法对定时时间进行微调。,例:,MOV R0,,,#TTME,;,LOOP,:,ADD A,,,R1,;,INC DPTR,;,DJNZ R0,,,LOOP,;,由于,ADD,、,INC,、,DJNZ,指令的机器周期分别为,1,、,2,、,2,,所以,,该程序定时时间为,=,(,1+2+2,),2sTime,(,s,),。,假定要求定时时间为,24us,。,对于这个定时程序,只须增加一条,NOP,指令即可实现。,MOV R0,,,#TIME,;,LOOP,:,ADD A,,,R1,;,INC DPTR,;,NOP,;,DJNZ R0,,,LOOP,;,只须,TIME,取,2,,即可得到精确的,24s,定时。,(,4,),以一个基本的延时程序满足不同的定时要求,如果一个系统有多个定时需要,我们就可以设计一个基本延时程序,使其延时时间为各定时时间的最大公约数,然后可以以此基本程序作为子程序,通过调用的方法实现所需不同定时。,例:在单片机应用系统中,假设需要的定时时间分别为,5S,、,10S,、,20S,,,可设计一个,1S,延时子程序,DELAY,,,则,5S,、,10S,、,20S,的定时时间可通过调用,DELAY,实现。,MOV R0,,,#05H,;,5S,定时,LOOP: LCALL DELAY,;,DJNZ R0,,,LOOP1,;,MOV R0,,,#0AH,;,10S,定时,LOOP2: LCALL DELAY,;,DJNZ R0,,,LOOP2,;,MOV R0,,,#14H,;,20S,定时,LOOP3: LCALL DELAY,;,DJNZ R0,,,LOOP3,;,4.3.3,查表程序,所谓查表程序,就是指预先把数据以表格形式存放在程序存储器中,然后使用程序读出,这种能读出表格数据的程序就称之为查表程序。,查表操作对单片机的控制应用十分重要,查表程序,常用于实现非线性修正,非线性函数转换以及代码转换等,场合。,MCS-51,单片机,指令系统中,有两条,专用查表指令:,(,1,),MOVC A,,,A+DPTR,;,A,(,A,),+,(,DPTR,),(,2,),MOVC A,,,A+PC,;,A,(,A,),+,(,PC,),这,两条,查表指令,的功能是完全相同的,其共同优点是:能在不改变,PC,和,DPTR,的状态下,只根据,A,的内容就可以取出表格中的数据。注意:,A,的内容均为,8,位无符号数。,对于第一条指令,适用于,64KB ROM,范围内查表(即数据表格的大小和位置可以在,64KB,程序存储器中任意安排,一个数据表格可以被多个程序块使用),编写查表程序时,首先把表的首地址送入,DPTR,中,再要将查表的数据序号(或下标值)送入,A,中,然后就可以使用该指令进行查表操作,并把结果送,A,中。,对于第二条指令,常用于“本地”范围查表(即数据表格只能放在该指令后面,256,个地址单元之内,而且表格只能被本程序使用),编写查表程序时,首先把查表数据的序号送入,A,中,再把从查表指令的下一条指令的首地址到表的首地址间的偏移量与,A,值相加,然后再使用该指令进行查表操作,并把结果送入,A,中。,例:设计一个子程序,其功能为根据,x,的内容(,0,9,之间)查平方表,求出相应的结果,y,(,y=x,2,)。,假设,x,的内容已存放在内部,RAM 30H,单元中,求出,y,的内容存放在内部,RAM 40H,单元中。,ORG 1000H,1000H SQR,:,MOV A,,,30H,;,Ax,1002H PUSH DPH,;,现场保护,1004H PUSH DPL,;,1006H MOV DPTR,,,#TAB1,;,DPTR,表首地址,TAB1,1009H MOVC A,,,A+DPTR,;,查表得,y,100AH MOV 40H,,,A,;,40Hy,100CH POP DPL,;,现场恢复,100EH POP DPH,;,1010H RET,1011H TAB1: DB 00H,,,01H,,,04H,,,09H,,,10H,,,19H,DB 24H,,,31H,,,40H,,,51H,上例中,如果使用,MOVC A,,,A+PC,指令,,则,编程如下:,ORG 1000H,1000H SQR,:,MOV A,,,30H,;,Ax,1002H PUSH DPH,;,现场保护,1004H PUSH DPL,;,1006H ADD A,,,#07H,;,加,偏移量,1008H MOVC A,,,A+PC,;,查表得,y,1009H MOV 40H,,,A,;,40Hy,100BH POP DPL,;,现场恢复,100DH POP DPH,;,100FH RET,1010H TAB1: DB 00H,,,01H,,,04H,,,09H,,,10H,,,19H,DB 24H,,,31H,,,40H,,,51H,此题,中,偏移量,=1010H-1009H=07H,4.4,单片机汇编语言源程序的编辑和汇编,4.5 80C51,单片机,汇编语言伪指令,汇编语言程序必须转换为二进制的机器代码程序,单片机才能够执行。汇编语言程序转换为机器代码程序的过程,称之为汇编。汇编的方法有两种:即机器交叉汇编和手工汇编。,所谓手工汇编,就是指程序设计人员通过查指令编码表,逐个把助记符指令,“,翻译,”,成机器码。手工汇编方法通常用于短、小程序的汇编。长程序则必须通过机器交叉汇编的方法进行汇编。,所谓机器交叉汇编,就是指程序设计人员使用一种计算机的汇编程序去汇编另一种计算机的源程序,具体地说就是运行汇编程序进行汇编的是一种计算机,而运行汇编得到的目标程序的则是另一种计算机。,单片机只能采用机器交叉汇编的方法对汇编语言程序进行汇编,对汇编语言程序进行机器交叉汇编时,必须告诉计算机的汇编程序应该如何完成汇编工作,这一任务就是通过使用伪指令来实现的。,伪指令是程序,设计人,员发给汇编程序的指令,也称汇编命令或汇编程序控制指令。,它具有控制汇编程序的输入输出、定义数据和符号、条件汇编、分配存储空间等功能。,伪指令没有与之相对应的二进制机器代码,因此,在汇编语言指令系统汇总表中,查不到相对应的二进制机器代码。不同汇编语言的伪指令也有所不同,但一些基本指令是相同的。,手工汇编不需要伪指令,但机器交叉汇编必须使用伪指令。在对汇编语言程序进行机器交叉汇编前,伪指令存在于汇编语言程序中,但汇编后得到的机器代码程序中不存在伪指令相对应的二进制机器代码,这一点请特别注意。,(,1,),ORG,(,ORiGin,),汇编起始地址命令,本命令总出现在汇编语言源程序的开头位置,用于规定目标程序的起始地址,即此命令后面的程序或数据块的起始地址。,命令格式:,标号:,ORG,地址,其中,标号:,是选择项,根据需要选用,,地址,项,通常为,16,位绝对地址,但也可以使用标号或表达式表示。,在汇编语言程序的开始,通常都用一条,ORG,伪指令来规定程序的起始地址,如果不用,ORG,规定,则汇编得到的目标程序将从,0000H,开始。,例:,ORG 8000H,即规定标号,START,代表地址,8000H,,,START,:,MOV A,,,#00H,;,目标程序的第一条指令从,8000H,开始。,(,2,),END,(,END of assembly,),汇编终止命令,本命令用于终止,汇编语言,源程序的汇编工作,,END,是汇编语言源程序的结束标志,,因此,在整个汇编语言,源程序,中,只能有一个,END,指令,,且位于程序的最后。如果,END,命令出现在程序中间,则,在,END,之后的指令,汇编程序,将,不予处理。,命令格式:,标号:,END,表达式,(,3,),EQU,(,EQUate,),赋值命令,本命令用于给字符名称赋予一个特定值,赋值以后,其值在整个程序中有效。,命令格式:,字符名称,EQU,赋值项,其中,赋值项,可以是常数,地址,标号或表达式,其值为,8,位,或,16,位,二进制数。赋值,以后的,字符名称,既可以作地址使用,也可以作立即数使用。,例:,HOUR EQU 30H,ORG 1000H,START,:,MOV HOUR,,,#40H,;,等同于,START,:,MOV 30H,,,#40H,;,(,4,),DB,(,Define Byte,),定义数据字节命令,本命令用于从指定的地址单元开始,在程序存储器的连续单元中定义字节数据。,命令格式:,标号:,DB8,位数表,常使用本命令存放数据表格。,例:存放,7,段数码管(共阳极)显示的十六进制基数(,0,F,),的十六进制数的字形代码,可使用多条,DB,命令定义。,DB 0C0H,,,0F9H,,,0A4H,,,0B0H,;,0,,,1,,,2,,,3,DB 99H,,,92H,,,82H,,,0F8H,;,4,,,5,,,6,,,7 DB 80H,,,90H,,,88H,,,83H,;,8,,,9,,,A,,,B,DB 0C6H,,,0A1H,,,86H,,,84H,;,C,,,D,,,E,,,F,查表时,为确定数据区的起始地址,可采用两种方法,:,a,),根据,DB,命令前一条指令的地址确定。把该地址加上它的字节数就是,DB,的定义的数据字节的起始地址。,例:,8100: MOV A, #49H,;,一字节指令,TAB: DB 0COH,,,0F9H,,,0A4H,,,0B0H,;,定义的,7,段数码管(共阳极)显示的十六进制基数(,0,F,),的十六进制数的字形代码,从,8101H,地址,单元,开始存放。,b,),使用,0RG,命令专门规定。,例:,ORG 8100H,TAB: DB 0COH,,,0F9H,,,0A4H,,,0B0H,;,定义的,7,段数码管(共阳极)显示的十六进制基数(,0,F,),的十六进制数的字形代码从,8101H,地址单元开始存放。,(,5,),DW,(,Define Word,),定义数据字命令,本命令用于从指定地址开始,在程序存储器单元中定义,16,位的数据字。,命令格式:,标号:,DW16,位数表,存放时,数据字的高,8,位在前(低地址),低,8,位在后(高地址)。,例:,DW,“,AA,”,;,存入,41H,,,42H,。,DB,和,DW,定义的数表,数的个数不得超过,80,个。如数据的数目较多时,可使用多个定义命令。,在,MCS-51,程序设计应用中,常以,DB,来定义数据,以,DW,来定义地址。,(,6,),DS,(,Define,Stonage,),定义存储区命令,本命令用于从指定地址开始,保留指定数目的字节单元作为存储器,供程序运行使用,汇编时,对这些单元不赋值。,命令格式:,标号:,DS 16,位数表,例:,ORG 8100H,DS 08H,从,8100H,地址开始,保留,8,个连续的地址单元。,(,7,),BIT,位定义命令,本命令用于给字符名称赋以位地址,命令格式:,字符名称,BIT,位地址,其中,位地址,可以是绝对地址,也可以是符号地址(即位符号名称),例:,AQ BIT P1.0,把,P1.0,的位地址赋给变量,AQ,,,在其后的编程中,,AQ,就可以作为位地址使用。,补充内容:子程序结构,子程序结构是一种非常重要的程序结构。在一个程序中经常遇到反复多次某程序段的情况,如果重复书写这个程序段,会使程序变得冗长而杂乱。对此,可采用子程序结构,即把重复的程序段编写为一个子程序,通过主程序调用而使用它。这样不但减少了编程工作量,而且也缩短了程序的长度。,调用和返回构成了子程序调用的完整过程。为了实现这一过程,必须有子程序调用指令和返回指令。调用指令在主程序中使用,而返回指令则应该是子程序的最后一条指令。执行完这条指令后,程序返回主程序断点处继续执行。,(,1,)子程序的编程原则,在实际的单片机应用系统软件设计中,为了程序结构更加清晰,易于设计,易于修改,增强程序可读性,基本上都要使用子程序结构。子程序作为一个具有独立功能的程序段,编程时需遵循以下原则:,a,),子程序的第一条指令必须有标号,明确子程序入口地址;,b,),以返回指令,RET,结束子程序;,c,),子程序说明部分;,子程序名称:提供给主程序调用的名字,通常用符号或子程,序第一条语句的标号来表示。,子程序功能:简要说明子程序能完成的主要功能。,子程序入口参数:主程序需要向子程序提供的参数。,子程序出口参数:子程序执行完之后向主程序返回的参数。,子程序占用资源:子程序中使用了哪些存储单元、寄存器等,子程序堆栈深度:子程序占用堆栈区的最大字节数。,子程序嵌套情况:子程序中继续调用子程序的情况。,子程序的字节数:子程序中所有指令字节数的总和。,子程序执行时间:子程序中所有指令的机器周期数总和。,这些说明是写给程序员看的,供以后使用子程序时参考。,d,),较强的通用性和可浮动性,尽可能避免使用具体的内存单元和绝对转移地址等。,e,),注意保护现场和恢复现场。,子程序在编制过程中经常会用到一些通用单元,如工作寄存器、累加器、数据指针,DPTR,以及,PSW,等。而这些工作单元在调用,它的主程序中也会用到,为此,需要将子程序用到的这些通用编程资源加以保护,称为保护现场。在子程序执行完后需恢复这些单元的内容,称为恢复现场。通常,保护和恢复现场是在子程序中利用堆栈操作实现的,在子程序的开始部分把子程序中要用到的编程资源都保护起来,在执行返回指令之前恢复现场,这是一种比较规范的方法。,另外,保护现场和恢复现场也可以在主程序,中实现。在调用子程序前保护现场,子程序返回后恢复现场,这种方式比较灵活,可以根据当时的需要确定要保护的内容。,(,2,)参数传递的方法,主程序调用子程序时,主程序和子程序之间存在着参数互相传递的问题。参数传递一般有以下几种方法:,1),寄存器传递参数,通过寄存器,A,传递入口参数和出口参数。,例:假设,a,、,b,均小于,10,,计算,c=a,2,+b,2,,,其中,a,事先存在内部,RAM,的,31H,单元,,b,事先存在,32H,单元,请把,c,存入,33H,单元。,SQR:y=x,2,子程序,ORG 0000H,;,主程序,MAIN,:,MOV SP,,,#3FH,;,设置栈底,MOV A,,,31H,;,取数,a,存放到,A,中作为入口参数,LCALL SQR,;,MOV R1,,,A,;,出口参数:,a,的平方值存放在,A,中,MOV A,,,32H,;,取数,b,存放到,A,中作为入口参数,LCALL SQR,;,ADD A,,,R1,;,MOV 33H,,,A,;,SJMP $,;,子程序名称,:,SQR,功能:通过查表求出平方值,y=x,2,入口参数:,x,存放在累加器,A,中,出口参数:求得的平方值,y,存放在,A,中,占用资源:累加器,A,,,数据指针,DPTR,SQR,:,PUSH DPH,;,保护现场,将主程序中,DPTR,的高,8,位入栈,PUSH DPL,;,保护现场,将主程序中,DPTR,的低,8,位入栈,MOV DPTR,,,#TABLE,;,在子程序中重新使用,DPTR,,,DPTR,表首地址,MOVC A,,,A+DPTR,;,查表,POP DPL,;,恢复现场,将主程序中,DPTR,的低,8,位从堆栈中弹出,POP DPH,;,恢复现场,将主程序中,DPTR,的高,8,位从堆栈中弹出,RET,TABLE: DB 0,,,1,,,4,,,9,,,16,,,25,,,36,,,49,,,64,,,81,END,2),利用堆栈传递参数*,ORG 0000H,;,主程序,MAIN,:,MOV SP,,,#3FH,;,设置栈底,PUSH 31H,;,将数,a,存放到堆栈中,作为入口参数,LCALL SQR,;,POP ACC,;,MOV R1,,,A,;,出口参数:,a,的平方值存放在,A,中,PUSH ACC,;,LCALL SQR,;,POP ACC,;,ADD A,,,R1,;,MOV 33H,,,A,;,SJMP $,;,子程序名称:,SQR,功能:通过查表求出平方值,y=x,2,入口参数:,x,存放在堆栈中,出口参数:求得的平方值,y,存放在堆栈中,占用资源:累加器,A,,,数据指针,DPTR,SQR,:,MOV R0,,,SP,;,R0,作为参数指针,DEC R0,;,堆栈指针退回子程序调用前的地址,DEC R0,;,XCH A,,,R0,;,保护,ACC,,,取出参数,MOV DPTR,,,#TABLE,;,DPTR,表首地址,MOVC A,,,A+DPTR,;,查表,XCH A,,,R0,;,查表结果放回堆栈中,RET,TABLE: DB 0,,,1,,,4,,,9,,,16,,,25,,,36,,,49,,,64,,,81,(,3,)子程序调用中应注意的问题,由于子程序调用过程中,,CPU,自动使用了堆栈,因此,容易出现以下几种错误:,a,),忘记给堆栈指针,SP,赋栈底初值,堆栈初始化位置与第,1,组工作寄存器重合,如果以不同的方式使用了同一个内存区域,会导致程序乱套。,b,),程序中的,PUSH,和,POP,没有配对使用,使,RET,指令执行时不能弹出正确的断点地址,造成返回错误。,c,),堆栈设置太小,堆栈操作增长太大,使栈区与其它内存单元重合。,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!