1、单片机应用技术,单片机应用技术,主讲教师:,苏晓龙,全校公共选修课,计算机学院信息科学系,办公室:计,A315-1,答疑地点:,计,A315-1,E-mail,:,suxl,第,4,章,汇编语言程序设计,4.1,汇编语言基本概念,4.2,汇编语言程序设计,4.1,汇编语言基本概念,4.1.1,程序设计语言,4.1.2,汇编语言的语句结构,4.1.3,伪指令,返回本章首页,4.1.1,程序设计语言,按照语言的结构及其功能可以分为三种:,1,机器语言:,机器语言是用二进制代码,0,和,1,表示指令和数据的最原始的程序设计语言。,2,汇编语言:,在汇编语言中,指令用助记符表示,地址、操作数可用标号、
2、符号地址及字符等形式来描述。,3,高级语言:,高级语言是接近于人的自然语言,面向过程而独立于机器的通用语言。,返回本节,4.1.2,汇编语言的语句结构,1,汇编语言的指令类型,MCS-51,单片机汇编语言,包含两类不同性质的指令。,(,1,)基本指令:,即指令系统中的指令。它们都是机器能够执行的指令,,每一条指令都有对应的机器码,。,(,2,)伪指令,(,指示性指令,),:,汇编时不生成机器指令,仅用于控制汇编的指令。是目标机不执行的指令,无机器码。,2,汇编语言的语句格式,返回本节,汇编语言源程序是由汇编语句(即指令)组成的。汇编语言的每一条语句一般由四部分组成。,标号:,助记符,操作数,;
3、注释,START,:,MOV A,,,30H,;,A,(,30H,),标号:,由,1,8,个字符组成的语句地址符号,必须以字母开头,其余字符可使用字母或数字。标号既可代表本条指令,也可代表本条指令操作码在,ROM,中存放的第一个存储单元地址。标号必须以冒号“,:,”结束。,助记符:,又称操作符,是指令的必不可少部分,它使用接近于人类自然语言的形式帮助人们记住指令的功能,如,MOV(,传送,),、,ORL(,或逻辑运算,),等。,操作数:,参加操作的数据或数据所在存储单元的地址。操作数允许没有、,1,个、,2,个或,3,个,按指令的操作功能而设置。当有多个操作数时,每个操作数之间用逗号“,”,隔
4、开。若有两个操作数,则目的操作数在前,源操作数在后。操作结果存放的存储单元称为目的操作数,操作数的来源称为源操作数。目的操作数与助记符之间用空格隔开。,2,汇编语言的语句格式,注解:,用分号“;”开头,为本条指令的操作功能说明。,按照有无操作数划分,指令可分成两大类:无操作数指令和有操作数指令。前一类指令由助记符组成;后一类指令由助记符和操作数组成。,4.1.3,伪指令,1,ORG,:汇编起始地址,用来说明以下程序段在存储器中存放的起始地址。,例如程序:,ORG1000H,START,:,MOVA,,,#20H,MOVB,,,#30H,2,EQU,:赋值,给变量标号赋予一个确定的数值。,为汇编
5、程序提供汇编说明的指令叫做伪指令。伪指令无机器代码,不能被执行。一个完整的汇编程序仅有可执行指令是不完善的,必须要有伪指令才能使程序完整。汇编过程离不开伪指令提供的信息。汇编程序中用到的伪指令如表,4-1,所示。,4.1.3,伪指令,分 类,伪指令,功 能,程序开始、结束,ORG,END,SEGMENT,表示程序的起始位置,表示源程序汇编结束,表示所生成的段再定为类型,数据定义,DB,DW,DS,DBIT,定义字节数据,定义字数据,以字节为单位预留空间,定义位地址数据,符号定义,EQU,BIT,SET,DATA,给符号名赋值,给符号名赋位地址,给符号名赋值且可以重新定义,给制定符号赋与内部地址
6、表,4-1,单片机伪指令,这些伪指令中,有,7,条是常用的,现介绍如下。,1.,程序起始地址伪指令,格式:,ORG 16,位地址,功能:,ORG,后面的,16,位地址就是源程序第,1,条指令的存放地址,位于程序,ROM,中。,例,4.1,ORG 0120H,START,:,MOV A,,,#80H,表示目标程序从,ROM,的,0120H,存储单元开始存放,,START,标号地址就是,0120H,。,2.,程序结束伪指令,格式:,END,或,END,标号,功能:表示汇编结束,位于源程序结尾处。子程序后面的,END,不用加标号;主程序后面的,END,需要加标号,该标号只能是,ORG,后面执行指令
7、的标号,即主程序第一条执行指令的标号或符号地址。,【,例,4.2】,主程序中,END,的位置。,ORG 0120H,START,:,MOV A,,,#80H,SJMP$,;本指令是执行指令,用于动态停 机,END START,;本指令是伪指令,不执行,表示汇编到此结束,3.,字节定义伪指令,格式:,标号:,DB,字节数据、字符或表达式,功能:在,ROM,中开辟数据存储区,以字节为单位依次存放着,DB,后面的数据。这些数据如果是字符,(,必须用单引号括起,),,将以,ASCII,码形式出现;如果是表达式,则存放着表达式的值。数据区的起始地址可以用标号代替。,【,例,4.3】,程序如下:,伪指令,
8、YYY,:,DB,01H,,,04H,,,09H,,,A,就是从,0124H,单元开始创建一个数据区,依次存放的内容是,(0124H),01H,,,(0125H),04H,,,(0126H),09H,,,(0127H),41H,,,其中,41H,是字符,A,的,ASCII,码,这个数据区的首址,0124H,可以使用标号,YYY,代替。,4.,字定义伪指令,格式:,标号:,DW,字数据、字符或表达式,功能:在程序,ROM,中开辟以字为单位存放的数据存储区,一个字占两个单元,依次存放。,例,4.4:,伪指令,ABC,:,DW,ABCDH,,,EFH,,,AB,要求汇编在程序,ROM,中从,ABC,
9、单元开始创建一个数据区,,以字为单位存放数据,从,ABC,单元依次存放,ABH,、,CDH,、,00H,、,EFH,、,41H,、,42H,。,5.,存储区定义伪指令,格式:,标号:,DS,数值,功能:从标号地址开始预留几个字节的存储单元,供程序备用。,DS,后面的数值就是预留的个数。该指令中也可以不要标号。,【,例,4.5】,ORG 300AH,DS 5,;从,300AH,单元开始,空出,5,个存储单元给程序使用,6.,符号定义伪指令,格式:,符号,EQU,数值或数值表达式,功能:汇编识别结果,把数值或数值表达式的值赋给符号,在下面的程序中若出现符号,它的大小就是所赋值。,【,例,4.6】,
10、X EQU 30H,;,X,30H,MOV A,X,;结果,A,30H,7.,位符号定义伪指令,格式:符号,BIT,位地址,功能:将位地址赋给符号,该符号只要出现就代表位操作地址。,【,例,4.7】,BINKOU BIT P1.0,;将位地址,P1.0,赋给 符号,BINKOU,CLR BINKOU,;,P1.0,清零,4.2,汇编语言程序设计,4.2.1,汇编语方程序设计步骤,4.2.2,顺序程序,4.2.3,分支程序,4.2.4,循环程序,4.2.5,子程序,4.2.6,位操作程序,返回本章首页,4.2.1,汇编语方程序设计步骤,1,分析问题,2,确定算法,3,设计程序流程图,4,分配内存
11、单元,5,编写汇编语言源程序,6,调试程序,返回本节,汇编语言程序的基本结构有,3,种:,顺序结构,分支结构,循环结构。,4.2.2,顺序程序,顺序程序是一种最简单,最基本的程序。,特点:,程序按编写的顺序依次往下执行每一条指令,直到最后一条。,【,例,4.2.1】,将,30H,单元内的两位,BCD,码拆开并转换成,ASCII,码,存入,RAM,两个单元中。程序流程如图所示。参考程序如下:,结束,取数据低,4,位,转换成,ASCII,码,存,ASCII,码,取数据高,4,位,转换成,ASCII,码,存,ASCII,码,开始,ORG2000H,MOV A,,,30H,;取值,ANL A,,,#0
12、FH,;取低,4,位,ADD A,,,#30H,;转换成,ASCII,码,MOV 32H,,,A,;保存结果,MOV A,,,30H,;取值,SWAPA,;高,4,位与低,4,位互换,ANL A,,,#0FH,;取低,4,位(原来的高,4,位),ADD A,,,#30H,;转换成,ASCII,码,MOV 31H,,,A,;保存结果,SJMP$,END,【,例,4.2.1】,将,30H,单元内的两位,BCD,码拆开并转换成,ASCII,码,存入,RAM,两个单元中。参考程序如下:,【,例,4.2.2】,设,X,、,Y,两个小于,10,的整数分别存于片内,30H,、,31H,单元,试求两数的平方和
13、并将结果存于,32H,单元。,解:,两数均小于,10,,故两数的平方和小于,100,,可利用乘法指令求平方。程序流程如图所示。参考程序如下:,结束,取数据,X,求,X,2,暂存,X,2,取数据,Y,求,Y,2,求,X,2,+Y,2,开始,保存平方和,ORG2000H,MOV A,,,30H,;取,30H,单元数据,MOV B,,,A,;将,X,送入,B,寄存器,MUL AB,;求,X,2,,结果在累加器中,MOV R1,,,A,;将结果暂存于,R1,寄存器中,MOV A,,,31H,;取,31H,单元数据,MOV B,,,A,;将,Y,送入,B,寄存器,MUL AB,;求,Y,2,,结果在累加
14、器中,ADD A,,,R1,;求,X,2,+Y,2,MOV 32H,,,A,;保存数据,SJMP$,;暂停,END,【,例,4.2.2】,试求,30H,、,31H,单元两数的平方和并将结果存于,32H,单元。,4.2.3,分支程序,1,分支程序的基本形式,分支程序有三种基本形式,如图,4-3,所示。,分支程序的设计要点如下:,(,1,)先建立可供条件转移指令测试的条件。,(,2,)选用合适的条件转移指令。,(,3,)在转移的目的地址处设定标号。,程序在执行过程中,要根据测试条件决定程序的走向,这种程序称为分支结构程序。,当程序从一条支路往下继续执行时,其它分支支路上的指令不再被执行。分支程序中
15、必须要有控制转移类指令,测试结果不同,程序的走向不同。,条件满足?,A,Y,N,(,a,),条件满足?,A,B,N,Y,(,b,),(,c,),A0,A1,An,K=0 K=1 K=n,K=,?,图,4-3,分支程序结构流程图,2,双向分支程序设计举例,【,例,4.2.3】,设,X,存在,30H,单元中,根据下式,X+2 X0,Y=100 X=0,求出,Y,值,将,Y,值存入,31H,单元。,X X0,解,:根据数据的符号位判别该数的正负,若最高位为,0,,再判别该数是否为,0,。程序流程如图,4-4,所示。,A,为负数?,取数,,A,(,30H,),开始,结束,A=0,?,Y,N,N,A,|
16、X|,A64H,A,X+2,存数,(,31H,),A,(,3,0H,),图,4-4,例,4.2.3,程序流程图,参考程序如下:,ORG1000H,MOV A,,,30H,;取数,JB ACC.7,,,NEG,;负数,转,NEG,JZ ZER0,;为零,转,ZER0,ADD A,,,#02H,;为正数,求,X+2,AJMP SAVE,;转到,SAVE,,保存数据,ZER0,:,MOVA,,,#64H,;数据为零,,Y=100,AJMP SAVE,;转到,SAVE,,保存数据,NEG,:,DEC A,;,CPLA,;求,X,SAVE,:,MOV31H,,,A,;保存数据,SJMP,;暂停,3,多向
17、分支程序设计举例,多路分支程序的特点是根据不同输入条件或运算结果,转去执行不同的处理程序。,多路分支程序通常使用间接转移指令,JMP A+DPTR,实现。具体操作可以通过查转移地址表或查转移指令表完成。使用转移地址表时,应事先将转移地址排成表格驻进存储器,表格的内容依次作为转移目标的地址。使用转移指令表时,同样需事先将不同程序的转移指令列成表格,查表时查到哪个程序的转移指令,就执行哪个程序。,3,多向分支程序设计举例,【,例,4.2.4】,根据,R0,的值转向,7,个分支程序。,R010,,转向,SUB0,;,R020,,转向,SUB1,;,R00,Y=100 X=0,求出,Y,值,并将,Y,
18、值放回原处。,X X0,解:,设置一个计数器控制循环次数,每处理完一个数据,计数器减,1,。程序流程如图,4-8,所示。,A=0,?,Y,Y,N,N,Y,N,A,为负数?,取数,,A,(,R1,),开始,结束,AX,A64H,AX+2,存数,(,R1,),A,(,3,0H,),设置地址指针,R1,、计数器,R0,初值,R1R1+1,;,R0R0-1,R0=0?,图,4-8,例,4.5,的程序流程图,返回本节,4.2.4,循环程序,参考源程序如下:,ORG2000H,MOV R0,,,#10,MOVR1,,,#30H,START,:,MOVA,,,R1,;取数,JB ACC.7,,,NEG,;若
19、为负数,转,NEG,JZZER0,;若为零,转,ZER0,ADDA,,,#02H,;若为正数,求,X+2,AJMP SAVE,;转到,SAVE,,保存数据,ZER0,:,MOVA,,,#64H,;数据为零,,Y=100,4.2.4,循环程序,AJMP SAVE,;转到,SAVE,,保存数据,NEG,:,DECA,CPLA,;求,X,SAVE,:,MOV R1,,,A,;保存数据,INC R1,;地址指针指向下一个地址,DJNZ R0,,,START,;数据未处理完,继,;,续处理,SJMP,;暂停,4.2.5,子程序,能够独立完成一段功能的小程序,称为子程序,例如完成两个字节相加、数制转换、求
20、补码等等。,子程序编好以后,存放在,ROM,的某个地方,当主程序需要时,就可以调用它。有了子程序,能够使主程序更为简练、明朗。子程序在设计时,除了一般程序设计的要求外,还有结合自身的一些注意事项。,子程序中必然要用到寄存器和存储单元,如果这些寄存器或存储单元在主程序中已经在使用,那么在调用子程序之前,必须首先把它们存放的内容推入堆栈中保护起来。,1,子程序概念,4.2.5,子程序,入栈操作通常在子程序一开始进行,因此,子程序一开始多为入栈指令。当子程序执行完毕返回主程序时,理应要把入栈的内容弹出到相应的寄存器或存储单元中,才不致于影响主程序的执行。出栈可以在返回主程序前进行。,1,子程序概念,
21、所谓调用子程序,暂时中断主程序的执行,而转到子程序的入口地址去执行子程序。如下图所示。,RET,LCALL SUB,4.2.5,子程序,1,子程序概念,调用子程序应注意:,(,1,)子程序占用的存储单元和寄存器。,(,2,)参数的传递。,(,3,)子程序经过调用后得到的数据来完成程序之间的参数传递。,(,4,)嵌套调用与递归调用。如下图所示。,LCALL A,RET,RET,LCALL B,4.2.5,子程序,1,子程序概念,子程序从主程序接收到的已知条件称为子程序的入口参数。子程序的运算结果称为出口参数。在调用子程序之前,主程序必须把入口参数设置恰当,满足子程序的要求。子程序也要把出口参数设
22、置恰当,才能让主程序享用。,入、出口参数在主、子程序之间传递时,要采取双方均认可并都能接受的方式。实现参数传递有多种方法,常用的有用累加器、用工作寄存器、用堆栈等几种传递参数方法,各种不同的传递参数方法有各自不同的优点。,2,子程序设计举例,4.2.5,子程序,【,例,4.2.6】,用工作寄存器传递参数。,两个,64,位无符号数相加。设两数分别放在,20H,和,30H,开始的单元中,各占,8,个字节,相加的和放在从,20H,开始的单元中。,;对主程序的要求:调用前将工作寄存器的内容入栈或暂存于寄存器或存储单元中。调用后直接从工作寄存器获取子程序结果,;调用子程序标号:,TWOADD,;入口参数
23、两数分别放在,20H,和,30H,开始的单元中,各占,8,个字节,,;出口参数:,20H,开始的,8,个单元中是相加的和,TWOADD,:,LOOP,:,LOOP1,:,ORG,PUSH,PUSH,PUSH,MOV,MOV,MOV,CLR,INC,INC,MOV,ADDC,MOV,0120H,R0,R1,R2,R0,,,#1FH,R1,,,#2FH,R2,,,#08H,C,R0,R1,A,,,R0,A,,,R1,R0 A,LOOP1,:,INC,INC,MOV,ADDC,MOV,DJNZ,POP,POP,POP,RET,R0,R1,A,,,R0,A,,,R1,R0 A,R2,,,LOOP1,
24、R2,R1,R0,4.2.6,位操作程序,【,例,4.2.7】,编写一程序,实现图中的逻辑运算电路。其中,P,3.1,、,P,1.1,、,P,1.0,分别是单片机端口线上的信息,,RS,0,、,RS,1,是,PSW,寄存器中的两个标志位,,30H,、,31H,是两个位地址,运算结果由,P,1.0,输出。,使用位操作指令的程序统称为位操作程序。这一类程序尤其适合于各种复杂的逻辑运算。,P,3.1,P,1.1,30H,31H,RS,1,RS,0,&,1,&,&,P,1.0,4.2.6,位操作程序,【,例,4.2.7】,程序如下:,ORG0000H,MOV C,,,P3.1,ANL C,,,P1.1
25、CPL C,MOV 20H,,,C,;暂存数据,MOV C,,,30H,ORL C,,,31H,ANL C,,,RS1,ANL C,,,20H,ANL C,,,RS0,MOV P1.0,,,C,;输出结果,SJMP$,习题与思考题,2.1 MCS-51,单片机的,1,条可执行指令由哪几部分组成?各部分分别起什么作用?,2.2,单片机指令长度有多少字节?,2.3,查表写出下列指令的机器码字节数和时钟周期数。,2.4,写出下列指令的机器码。,(1)ANL C,,,/34H,(2),RET,(3),MOV R4,,,A,(4),PUSH 45H,(5),DEC R,(6)SUBB A,,,R5,(
26、1)ADD A,,,#FBH,(2),ORL 45H,,,A,(3),CPL A,(4)DIV AB,(5),INC R0,(6),POP 68H,2.5,设单片机晶振时钟频率为,12 MHz,,写出下列指令的执行时间。,2.6,写出下列指令源操作数和目的操作数的寻址方式。,(1),RR A,(2),XCH A,,,40H,(3),JBC 23H,,,NEXT,(4)MOV R6,,,A,(5),NOP,(6),RETI,(1),ORL C,,,45H,(2),ORL A,,,45H,(3),MOV A,,,45H,(4)ADDC A,,,45H,(5)XRL 45H,,,A,(6)ORL 4
27、5H,,,A,2.7,判断下列,MCS-51,单片机指令是否正确。,ADD A,,,R7,ADD R7,,,A,SUB A,,,R7,SUBB A,,,R7,INC B,INC C,MUL AB,MUL BA,MOVX A,,,R0,MOVX A,,,R0,MOVX R0,,,A,MOVX R0,,,A,PUSH R0,PUSH 40H,PUSH DPTR,PUSH DPL,POP A+PC,POP E0H,POP DPTR,POP DPH,2.8,有几条指令能使,A,00H,,试写出。,2.9,以下各程序段在执行前都有,A,06H,,,B,BBH,,,CY,1,,,(20H),58H,,,(
28、21H),AAH,,,R0,39H,,,R1,8CH,,写出每个程序段的运行结果。,程序段,1,:,MOV,MOV,MOV,A,,,20H,C,,,20H,21H,,,C,问,A,_ (20H),_ (21H),_,程序段,2,:,LOOP,:,MOV,MOV,DJNZ,INC,DPL,,,R0,DPH,,,A,R0,,,LOOP,DPTR,问,A,_ R0,_ DPTR,_,程序段,3,:,MOV,MOV,XCHD,RR,20H,,,B,R0,,,#20H,A,,,R0,A,问,A,_ R0,_ (20H),_ B,_,程序段,4,:,MUL,ANL,CLR,ADD,AB,A,,,B,C,A
29、B,问,A,_ B,_ C,_,程序段,5,:,XCH,SUBB,SWAP,ORL,A,,,21H,A,,,21H,A,21H,,,A,问,A,_ (21H),_,2.10,累加器,A,内是一个有符号二进制数的补码,编一程序使,A,的内容为原数据的绝对值。,2.11,在,21H,、,20H,单元中存放着一个无符号,16,位二进制数,高字节在,21H,中。编程序将该数左移两位,仍放在这两个单元中。,2.12,编程实现:,Y,2.13,编程将片内,20H,单元开始的,30,个单元全部清零。,2.14,在片内,RAM 20H,单元开始存放有,20,个有符号字节数据,编程统计其中大于,10,的数有多少个?将个数放入,R7,中。,2.15,编程实现下列逻辑关系:,2.16,编延时程序,分别能延时,1,秒,,1,分,,1,小时。,2.17,编程从,P1.3,输出周期为,50 ms,的方波。,2.18,编查表程序,查找英文大写字母,A,Z,的,ASCII,码字符表。,2.19,编程计算片外,RAM 2000H,开始存放的,10,个数的平均值,计算结果存入从,3000H,开始的两个单元中。,