《第5章 51系列单片机汇编语言程序设计及仿真调试.ppt》由会员分享,可在线阅读,更多相关《第5章 51系列单片机汇编语言程序设计及仿真调试.ppt(111页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、华东交通大学徐春辉制作华东交通大学徐春辉制作单片微机原理单片微机原理及应用及应用华东交通大学徐春辉制作华东交通大学徐春辉制作2013年年8月月华东交通大学徐春辉制作华东交通大学徐春辉制作第第5 5章章 5151系列系列单片机单片机汇编语言汇编语言程序设计及仿真调试程序设计及仿真调试华东交通大学徐春辉制作华东交通大学徐春辉制作 内容内容提要提要 本章介绍汇编语言程序设计的有关知识,重点介绍利用51系列单片机汇编语言实现主要的程序结构及基本功能程序的设计。然后通过一些实例进一步介绍汇编语言程序设计的方法和技巧。最后介绍汇编语言源程序的仿真调试及开发工具Keil Vision的使用。学习学习要点要点
2、 了解汇编语言编程的基础知识。了解汇编语言程序设计的基本步骤和方法。掌握单片机汇编语言的顺序、分支、循环、查表及子程序的结构。掌握码制转换、查表、散转、算术运算等常用程序的编制方法。掌握集成开发环境Keil Vision的基本操作,能应用其调试程序。华东交通大学徐春辉制作华东交通大学徐春辉制作5.1 汇编语言程序设计基础汇编语言程序设计基础5.2 汇编语言源程序的基本结构汇编语言源程序的基本结构5.3 51系列单片机汇编语言实用程序设计系列单片机汇编语言实用程序设计举例举例5.4 程序调试与集成开发环境软件程序调试与集成开发环境软件Keil Vision 第第5 5章章 目目 录录华东交通大学
3、徐春辉制作华东交通大学徐春辉制作5 5.1 5.1 汇编语言程序设计基础汇编语言程序设计基础 5.1.1 机器语言、汇编语言与高级语言机器语言、汇编语言与高级语言 1机器语言机器语言 计算机能直接识别和执行的是二进制代码形式的机器指令,而这类指令的集合就是计算机的机器语言,或称指令系统。机器语言是面向计算机系统的。机器语言是最底层的程序设计语言,其他语言编写的程序最终都要转换为机器语言的形式。用机器语言编写的程序称为目标程序或机器语言程序。由于机器语言可以被计算机直接识别和执行,因而其执行速度最快。华东交通大学徐春辉制作华东交通大学徐春辉制作6 2汇编语言汇编语言 汇编语言是用助记符(英文字母
4、缩写)来表示的面向机器的程序设计语言,每条助记符指令都有相对应的机器码,即汇编语言是机器语言的符号表示。图5-1 源程序与目标程序的关系华东交通大学徐春辉制作华东交通大学徐春辉制作7 3高级语言高级语言 高级语言(如C+等)克服了汇编语言的缺点,是一种面向问题或过程的语言。它是一种接近于自然语言和数学算法的语言,与机器的硬件无关,用户编程时不必仔细了解所用计算机的具体性能和指令系统。高级语言不但直观、易学、易懂,而且通用性强,可以在不同的计算机上运行,因此可移植性好。但是用高级语言编写的程序是不能直接执行的,需要由编译程序或解释程序将它们翻译成对应的目标程序,机器才能接受和执行。华东交通大学徐
5、春辉制作华东交通大学徐春辉制作8 5.1.2 汇编语言的语句和格式汇编语言的语句和格式 1汇编语言的语句汇编语言的语句 汇编语言的语句有两种基本类型:指令语句和指示性语句。(1)指令语句)指令语句 指令语句由指令系统中的指令构成。每一指令语句在汇编时都产生一个相应的指令代码(机器码),执行该指令代码对应着机器的一种操作。(2)指示性语句)指示性语句 指示性语句由伪指令构成,是控制汇编(翻译)过程的一些控制命令。在汇编时没有机器代码与之对应。华东交通大学徐春辉制作华东交通大学徐春辉制作9 2汇编语言语句的格式汇编语言语句的格式 汇编语言语句一般由4个字段组成,即标号、操作码、操作数和注释,它们之
6、间应用分隔符隔开,常用的分隔符有空格“”、冒号“:”和分号“;”,而且空格的数目可以不止一个。汇编语言语句的格式如下:汇编语言语句的格式如下:标号:标号:操作码操作码 操作数操作数 ;注释;注释 上述格式中,中的项为任选项,其中标号与操作码之间用“:”分隔,操作码与操作数之间用空格分隔,操作数与注释之间用“;”分隔,有多个操作数时,操作数和操作数之间用“,”分隔。华东交通大学徐春辉制作华东交通大学徐春辉制作10 例如,标号:操作码 操作数 ;注释 LOOP:MOV A,30H ;(30H)A华东交通大学徐春辉制作华东交通大学徐春辉制作11 上述4个字段应该遵守的基本语法规则个字段应该遵守的基本
7、语法规则如下。(1)标号字段)标号字段 标号是语句所在地址的标志符号,有了标号,该语句才能被程序中的其他语句所访问。有关标号规定如下:标号由18个ASCII码字符组成,第一个字符必须是字母。同一标号在一个程序中只能定义一次,不能重复定义。不能使用汇编语言已经定义的符号作为标号,如指令助记符、伪指令及寄存器的符号名称等。标号的有无,取决于本程序中的其他语句是否访问该条语句。如无其他语句访问,则该语句前不需要标号。华东交通大学徐春辉制作华东交通大学徐春辉制作12 (2)操作码字段)操作码字段 操作码是指令的助记符,表示指令的性质,用于指示CPU执行何种操作。操作码是汇编语言指令中唯一不能空缺的部分
8、。华东交通大学徐春辉制作华东交通大学徐春辉制作13 (3)操作数字段)操作数字段 操作数字段用于存放指令的操作数或操作数的地址。在本字段中,操作数的个数因指令的不同而不尽相同。通常有单操作数、双操作数和无操作数三种情况。如果是双操作数,则操作数之间要以逗号隔开。在操作数的表示中,有以下几种情况需要注意几种情况需要注意:十六进制、二进制和十进制形式的操作数表示 多数情况下,操作数或操作数的地址是采用十六进制形式来表示的,此时需加后缀H。在某些特殊场合用二进制表示,此时加后缀B,若操作数采用十进制形式,则需加后缀D,也可省略。如果十六进制操作数以数码AF开头,则需在它前面加一个0,以便汇编时把它和
9、作为字符的AF区别开。华东交通大学徐春辉制作华东交通大学徐春辉制作14 工作寄存器和特殊功能寄存器的表示 当操作数为工作寄存器或特殊功能寄存器时,允许用工作寄存器和特殊功能寄存器的代号表示。例如,工作寄存器用R7R0表示,累加器用A(或ACC)表示。另外,工作寄存器和特殊功能寄存器也可用其地址来表示,如累加器A可用其地址E0H来表示。操作数可以是参与运算的数或数的地址,有以下几种表示方法:立即数:#data和#data16。直接地址:direct,如30H;伪指令定义的符号地址,如SUM;表达式,如SUM+1,特殊功能寄存器的名字等。华东交通大学徐春辉制作华东交通大学徐春辉制作15 (4)注释
10、字段)注释字段 注释是为便于读者的阅读和理解而对语句或程序段的说明,汇编时不被翻译成机器码,机器也不执行。华东交通大学徐春辉制作华东交通大学徐春辉制作16 5.1.3 伪指令伪指令 伪指令是在“机器汇编”过程中,用来对汇编过程进行某种控制或者对符号和标号进行赋值。这些指令不属于指令系统中的指令,汇编时也不产生机器代码,因此称为“伪指令”。利用伪指令可以告诉“汇编程序”如何进行汇编,比如程序应放在何处、标号地址的具体取值等。华东交通大学徐春辉制作华东交通大学徐春辉制作17 1ORG(汇编起始地址伪指令)(汇编起始地址伪指令)ORG用来定义汇编以后的目标程序的起始地址。其格式如下:标号:标号:OR
11、G addr16 例如:ORG 2000H START:MOV A,#34H ORG规定了标号START的地址为2000H,也就是说该程序应从2000H开始存放。在一个汇编语言源程序中,可以多次使用ORG命令,以规定不同程序段的起始地址,地址一般应从小到大且不能重复。如果在程序开始处未定义ORG命令,则程序的起始地址默认为0000H。华东交通大学徐春辉制作华东交通大学徐春辉制作18 2END(汇编结束伪指令)(汇编结束伪指令)END用来表示汇编语言源程序结束,它只能出现在程序的末尾,且只有一个。其指令格式如下:标号:标号:END 指令的标号通常可以省略。在机器汇编时,汇编程序检测到该语句时便确
12、认汇编语言源程序全部结束,对其后的指令不再进行汇编。华东交通大学徐春辉制作华东交通大学徐春辉制作19 3EQU(赋值伪指令)(赋值伪指令)EQU用来对程序中出现的标号进行赋值。其格式如下:格式如下:字符名称字符名称 EQU 数或汇编符号数或汇编符号 在机器汇编时,汇编语言会自动将EQU后面的数或汇编符号赋给左侧的字符名称。例如,AA EQU R1 ;AA等同于R1K1 EQU 40H ;K1代表40H 使用该指令必须注意以下几点:注意以下几点:(1)该指令中的字符名称不是转移指令中出现的标号,而是出现在操作数中的字符名称。(2)EQU伪指令中的字符名称必须先定义后使用。(3)EQU定义的字符名
13、称不能出现在表达式中,例如语句MOV A,A10+1是错误的。华东交通大学徐春辉制作华东交通大学徐春辉制作20 4DATA(数据地址赋值伪指令)(数据地址赋值伪指令)DATA对数据地址或代码地址赋予规定的字符名称。其格式如格式如下:下:标号名称标号名称 DATA 表达式表达式 DATA伪指令的功能与EQU有些类似,可以将一个表达式的值赋给一个字符名称,但它与与EQU指令有如下区别:指令有如下区别:(1)表达式可以是一个数据或地址,但不可以是汇编符号(如R0R7)。(2)DATA语句定义的字符名称可以先使用后定义,故该语句放在程序的开头或末尾皆可。华东交通大学徐春辉制作华东交通大学徐春辉制作21
14、 5DB、DW、DS(定义字节、字、空间伪指令)(定义字节、字、空间伪指令)DB:从指定的地址单元开始,存放若干字节。DW:从指定的地址单元开始,存放若干字(16位二进制数,高8位在前,低8位在后)。DS:从指定的地址单元开始,保留若干单元备用。指令格式指令格式如下:如下:标号:标号:DB 字节常数字节常数;用逗号分隔开的若干项,每项都是一个字节)标号:标号:DW 字常数字常数 ;用逗号分隔开的若干项,每项都是一个字)标号:标号:DS 表达式表达式 ;其值表示保留的单元个数)华东交通大学徐春辉制作华东交通大学徐春辉制作22 【例5-1】分析下段程序。ORG 2000HDS 08HDB 30H,
15、8AH,10,BDW 54H,1F80H 解:该程序的DS伪指令定义8个存储单元(2000H2007H)备用;DB伪指令定义了从地址2008H开始的4个单元的内容;DW伪指令定义了后续4个单元的内容。结果如下:(2008H)=30H,(2009H)=8AH(200AH)=0AH,(200BH)=42H(200CH)=00H,(200DH)=54H(200EH)=1FH,(200FH)=80H华东交通大学徐春辉制作华东交通大学徐春辉制作23 6BIT(位地址符号伪指令)(位地址符号伪指令)BIT用来将位地址赋给字符名称。其格式为:格式为:字符名称字符名称 BIT 位地址位地址 例如:KEY BI
16、T P1.0 ;将P1.0的位地址赋给符号名KEY ST BIT 0D7H ;将位地址为D7H的位定义为符号名 注意:位地址既可以是绝对地址,也可以是符号地址。另外,用BIT定义的“符号名”一经定义便不能重新定义和改变。华东交通大学徐春辉制作华东交通大学徐春辉制作24 5.1.4 汇编语言源程序的汇编汇编语言源程序的汇编 汇编是将汇编语言源程序翻译成目标程序的过程,分为“人工汇编”和“机器汇编”。机器汇编是通过翻译程序来完成的,但在条件不具备的情况下也可以通过人工查表的方法人工查表的方法来汇编。1第一次汇编第一次汇编 首先首先通过查表通过查表查出每条指令的机器码,然后根据ORG规定的地址确定每
17、条指令所在的地址单元,形成目标程序。对程序中出现的转移指令标号和地址偏移量,仍然采用原来的符号暂不处理,而伪指令定义的符号地址应用实际值代入。华东交通大学徐春辉制作华东交通大学徐春辉制作25 2第二次汇编第二次汇编 计算计算转移指令中的标号地址转移指令中的标号地址,计算方法见下面的例子。【例5-2】对下面的源程序进行人工汇编。解:第一步查表,结果如下:地址 目标程序 源程序 ORG 2000H 2000H 7F 09 START:MOV R7,#09H 2002H 78 31 MOV R0,#31H 2004H E6 MOV A,R0 2005H 08 LOOP:INC R0 2006H 26
18、 ADD A,R0 2007H DF LOOP DJNZ R7,LOOP 2009H F5 30 MOV 30H,A 200BH 80 HALT HALT:SJMP HALT END华东交通大学徐春辉制作华东交通大学徐春辉制作26 第二步计算转移指令中的地址偏移量:(1)LOOP:DJNZ R7,LOOP 指令中的条件成立时,程序发生转移,即从地址2009H转移到2005H,故地址偏移量rel=2005H 2009H=04H,以补码形式表示为LOOP=FCH。(2)HALT:SJMP HALT执行之后,相当于从地址200DH转移到200BH,即地址偏移量rel=200BH-200DH=-02H
19、,以补码形式表示为HALT=FEH。将计算结果代入上述目标程序的标号即完成汇编。华东交通大学徐春辉制作华东交通大学徐春辉制作27 5.1.5 汇编语言程序设计的一般步骤汇编语言程序设计的一般步骤 汇编语言程序设计大致可分成以下几步:分成以下几步:(1)明确设计要求。(2)确定算法。(3)绘制程序流程图。(4)按程序流程图编写源程序。(5)上机调试。(6)优化程序。华东交通大学徐春辉制作华东交通大学徐春辉制作28 5.2 5.2 汇编语言源程序的基本结构汇编语言源程序的基本结构 再复杂的程序也是由简单程序组合起来的,掌握了程序的基本结构就拥有了程序设计的基本能力。单片机汇编语言源程序包括:顺序、
20、分支、循环及子程序4种基本结构。5.2.1 顺序结构顺序结构 顺序结构程序是一种最简单、最基本的程序(也称为简单程序),其特点是按程序编写的顺序依次执行,程序流向不变。顺序结构程序是所有复杂程序的基础及基本组成部分。华东交通大学徐春辉制作华东交通大学徐春辉制作29 【例5-3】将片内RAM的20H单元中的压缩BCD码拆成两个ACSII码存入21H、22H单元。低4位存在21H单元,高4位存在22H单元。解:(1)确定算法)确定算法:首先将压缩BCD码拆成两个单字节的BCD码,然后分别转换为对应的ACSII码。(2)画流程图)画流程图:根据算法画图,如图5-2所示。(3)编写源程序编写源程序:根
21、据流程图编写源程序如下所示:华东交通大学徐春辉制作华东交通大学徐春辉制作30ORG 2000HMOV A,20HMOV B,#10H;除以10HDIV ABORL B,#30H;低4位BCD码转换为ASCII码MOV 21H,BORL A,#30H;高4位BCD码转换为ASCII码MOV 22H,AEND图5-2华东交通大学徐春辉制作华东交通大学徐春辉制作31 【例5-4】编程将外部数据存储器的000DH和000EH单元的内容相换。解:外部数据存储器的数据操作只能用MOVX指令,且只能和A之间传送,因此必须用一个中间环节作为暂存,设用30H单元。用R0、R1指示两单元的低8位地址,高8位地址由
22、P2指示。汇编语言源程序清单如下:华东交通大学徐春辉制作华东交通大学徐春辉制作32ORG 0000HMOV P2,#0H ;送地址高8位至P2口MOV R0,#0DH ;R0=0DHMOV R1,#0EH ;R1=0EHMOVX A,R0 ;A=(000DH)MOV 30H,A ;(30H)=(000DH)MOVX A,R1 ;A=(000EH)XCH A,30H ;(30H)A,A=(000DH),(30H)=(000EH)MOVX R1,A MOV A,30HMOVX R0,A ;交换后的数送各单元SJMP$END华东交通大学徐春辉制作华东交通大学徐春辉制作33 5.2.2 分支结构分支结
23、构 通常情况下,程序的执行是按照指令在程序存储器中存放的顺序进行的,但根据实际需要也可以改变程序的执行顺序,这种程序结构就被称为分支结构,分支结构可分为单分支和多分支两种情况,如图5-3所示。华东交通大学徐春辉制作华东交通大学徐春辉制作34图5-3华东交通大学徐春辉制作华东交通大学徐春辉制作35 1单分支程序单分支程序 程序的判别仅有两个出口,两者选一,称为单分支选择结构。一般根据运算结果的状态标志,用条件转移指令来选择并转移。【例5-5】求单字节有符号数的二进制补码。解:在机器中,有符号数通常是用补码表示的,再求其补码,得到的就是其原码。正数的补码是其本身,负数补码是其反码加1。因此,应首先
24、判断被转换数的符号,负数进行转换,正数本身即为补码。由此,设计程序框图如图5-4 所示。华东交通大学徐春辉制作华东交通大学徐春辉制作 36 根据流程图编写程序如下:GCMPT:JNB ACC.7,RETURN;(A)0,不需转换 MOV C,ACC.7 ;符号位保存 CPL A ;(A)求反,加1 ADD A,#1 MOV ACC.7,C ;符号位回存A的最高位 RETURN:RET图5-4 华东交通大学徐春辉制作华东交通大学徐春辉制作37 2多分支结构多分支结构 当程序的判别部分有两个以上的出口时,为多分支结构。51单片机指令系统中并没有多分支转移指令,无法使用一条指令完成多分支转移。要实现
25、多分支转移,可根据情况采用下面的两种两种方法。方法。(1)多次使用条件转移,以转向不同的分支入口。)多次使用条件转移,以转向不同的分支入口。【例5-6】设变量x以补码形式存放在片内RAM的20H单元中,变量y与x的关系是 试编写程序,根据x的值求y的值,并放回原单元中。华东交通大学徐春辉制作华东交通大学徐春辉制作38解:流程图如图5-5所示,程序编制如下:ORG 1000HSTART:MOV A,20H ;取x至累加器 JZ NEXT ;x=0,转移 ANL A,#80H ;否,则屏蔽非符号位 JZ ED ;x 0,不作处理返回 MOV A,#05H ;x 0,x+05H送y ADD A,20
26、H MOV 20H,A SJMP ED NEXT:MOV 20H,#0AH ;x=0,10送yED:RET图5-5华东交通大学徐春辉制作华东交通大学徐春辉制作39 (2)利用间接转移指令)利用间接转移指令“JMP A+DPTR”转向不同的分支入口,具体的实现方法将在散转程序设计中做详细介绍。华东交通大学徐春辉制作华东交通大学徐春辉制作405.2.3 循环结构循环结构华东交通大学徐春辉制作华东交通大学徐春辉制作41 1循环程序的结构循环程序的结构 不论哪一种结构形式的循环程序,都由以下4个部分组成:(1)循环初始化)循环初始化。循环初始化用于完成循环前的准备工作。(2)循环体)循环体。循环程序结
27、构的核心部分,完成实际的处理工作,是需反复循环执行的部分,故又称循环体。这部分程序的内容,取决于实际处理问题的本身。(3)循环控制)循环控制。在重复执行循环体的过程中,不断修改循环控制变量,直到符合结束条件,就结束循环程序的执行。(4)循环结束)循环结束。这部分是对循环程序执行的结果进行分析、处理和存放。华东交通大学徐春辉制作华东交通大学徐春辉制作42 2循环结构的控制循环结构的控制 根据循环控制部分的不同,循环程序结构可分为计数控制循环结构和条件控制循环结构。(1)计数控制循环结构)计数控制循环结构 计数循环控制结构依据计数器的值来决定循环次数,一般为减“1”计数器,计数器减到“0”时,结束
28、循环。计数器的初值在初始化时设定,控制结构如图5-7所示。利用DJNZ指令可以很方便地实现这种控制结构。图5-7华东交通大学徐春辉制作华东交通大学徐春辉制作43 【例5-7】设有100个单字节数。连续存放在内部M单元开始的数据存储器中,且总和也为单字节数,存放到N单元。试编写求这100个数之和的程序。解:若用简单程序编写,需要99条加法指令进行相加,这样的算法显然是不科学的,应该使用循环程序。程序流程如图5-8所示。华东交通大学徐春辉制作华东交通大学徐春辉制作44参考程序:N EQU30HM EQU31H ORG 2020H MOV A,#00H MOV R0,#M MOV R1,#64HLO
29、OP:ADD A,R0 INCR0 DJNZ R1,LOOP MOV N,A SJMP$END华东交通大学徐春辉制作华东交通大学徐春辉制作45 (2)条件控制循环结构)条件控制循环结构 计数控制方法只有在循环次数已知的情况下才适用。对循环次数未知的问题,不能用循环次数来控制。往往需要根据某种条件来判断是否应该终止循环。条件控制结构如下图所示。华东交通大学徐春辉制作华东交通大学徐春辉制作46 【例5-9】假设在起始地址为M的内部数据存储器中放有100个数,其中有一个数的值等于FFH,试编程序,求出这个数的地址,送N单元。若这个数不存在,则将00H送入N单元。解:程序流程图如图5-10所示。华东交
30、通大学徐春辉制作华东交通大学徐春辉制作47N EQU08HM EQU09H ORG 1000H MOV R0,#M MOV R1,#64HLOOP:CJNER0,#0FFH,W SJMP W2W:INCR0 DJNZ R1,LOOP MOV N,#00H SJMP W3W2:MOV N,R0W3:SJMP$图5-10华东交通大学徐春辉制作华东交通大学徐春辉制作48 3多重循环多重循环 多重循环即循环嵌套结构。内循环属于外循环循环体中的具体处理部分。在多重嵌套中,不允许各个循环体互相交叉,也不允许从外循环跳入内循环,否则编译时会出错。注意的是每次通过外循环进入内循环时,内循环的初始条件需要重置。
31、循环嵌套结构如图5-11所示。图5-11华东交通大学徐春辉制作华东交通大学徐春辉制作49 【例5-10】设晶振为12MHz,试编写50ms延时程序。解:单片机运行中常常会有延时的需求,实现延时功能的常用方法有两种:一是用定时器中断来实现,二是用延时程序来实现。在系统时间允许的情况下,可以采用后一种方法。延时程序与指令执行时间有很大的关系。在使用12MHz晶振时,一个机器周期为1s。可采用如下双重循环结构编制延时程序。华东交通大学徐春辉制作华东交通大学徐春辉制作50程序如下:DEL50:MOV R7,#200;外循环执行1次DEL1:MOV R6,#123;执行200次 NOP;执行200次DE
32、L2:DJNZ R6,DEL2;执行200123次 DJNZ R7,DEL1;执行200次RET 查表知MOV Rn,#data是1机器周期指令,NOP是1机器周期指令,DJNZ Rn,rel是2机器周期指令。此程序实际运行时间为1+200(1+1+1232+2)1s=50.001ms。注意:软件延时程序执行过程中不允许有中断调用产生,否则将严重影响定时的准确性。华东交通大学徐春辉制作华东交通大学徐春辉制作51 5.2.4 子程序子程序 在实际应用中,经常有一些通用性的功能在程序中会多次被用到(比如显示、排序、查找、延时等)。为了节约存储空间,使程序变得更加紧凑、结构更清晰,往往将这些功能编成
33、一个个的子程序(过程、函数)以备调用。在编写或使用子程序时应注意以下问题。华东交通大学徐春辉制作华东交通大学徐春辉制作52 1子程序的定义子程序的定义 子程序的编写方法类似于一般程序,但应满足通用性应满足通用性的要求,即不针对具体数据编程。子程序的第一条指令的地址子程序的第一条指令的地址称为子程序的入口地址。该指令前必须有标号标号,以供调用,该标号即为子程序的名字名字。子程序结尾用RET指令来返回原调用处。子程序注释需提供足够的调用信息,比如子程序名、子程序功能、入口参数和出口参数、子程序占用的硬件资源、子程序中调用的其他子程序名等。华东交通大学徐春辉制作华东交通大学徐春辉制作53 2子程序的
34、调用与返回子程序的调用与返回 通过调用类指令(ACALL、LCALL)后写上子程序的入口地址来调用子程序。子程序的调用过程中所做的操作是先保存返回地址,而后转入子程序执行指令。在程序的最后使用RET指令,所做的操作就是将压入堆栈的返回地址弹出给PC,使程序接着顺序执行调用类指令后面的指令序列。华东交通大学徐春辉制作华东交通大学徐春辉制作54 3注意设置堆栈指针注意设置堆栈指针 因为系统初始化时SP的值被设置为07H,为防止栈区与可能用到的工作寄存器区相冲突,要注意重新设置堆栈指针。如果有子程序嵌套问题或堆栈深度比较深,则还须考虑堆栈容量,以免栈区位考虑堆栈容量,以免栈区位置安排过高造成堆栈溢出
35、的错误。置安排过高造成堆栈溢出的错误。华东交通大学徐春辉制作华东交通大学徐春辉制作55 4现场保护与恢复工作现场保护与恢复工作 由于主调程序和子程序经常是分开编制的,所以它们所使用的寄存器或存储单元往往会发生冲突。为避免子程序在运行过程中,修改主调程序中使用的寄存器/存储单元的原有内容,在子程序开始运行时应进行相应寄存器/存储单元内容的保存,在子程序运行结束,再将这些寄存器/存储单元的内容进行恢复,以保证调用程序的正常运行。原则上子程序中使用过的寄存器应该保存子程序中使用过的寄存器应该保存,但用于传递参数的寄存器则无须保存。注意,如果有较多的寄存器要保护,则应使主、子程序使用不同的寄存器组使用
36、不同的寄存器组。华东交通大学徐春辉制作华东交通大学徐春辉制作56 注意,由于堆栈是“后进先出后进先出”,所以使用堆栈来保存寄存器的内容时要注意保存和恢复的顺序。现场保护与恢复的实现通常有如下两种方法。(1)在主程序中实现)在主程序中实现 现场保护与恢复工作在主程序中实现,特点是结构灵活。例如,PUSH PSW ;保护现场(含当前工作寄存器组号)PUSH ACC PUSH B MOV PSW,#10H;切换当前工作寄存器组LCALL addr16 ;子程序调用POP B ;恢复现场POP ACC POP PSW ;含当前工作寄存器组切换华东交通大学徐春辉制作华东交通大学徐春辉制作57 (2)在子
37、程序中实现)在子程序中实现 现场保护与恢复工作在子程序中实现,特点是程序结构规范、清晰。例如,SUB1:PUSH PSW ;保护现场(含当前工作寄存器组号)PUSH ACC PUSH B MOV PSW,#10H;切换当前工作寄存器组 POP B ;恢复现场 POP ACC POP PSW ;内含当前工作寄存器组切换 RET华东交通大学徐春辉制作华东交通大学徐春辉制作58 5参数的传递参数的传递 主程序调用子程序时,往往需要把子程序所需的初始数据(入口参数)设置好,子程序执行完毕返回主程序时,也往往需要将子程序的执行结果(出口参数)带回给主程序。参数参数传送传送,实际上就是事先约定参数的获取方
38、式。常用的参数传递方式主要有常用的参数传递方式主要有:寄存器传送参数、存储器传送参数和堆栈传送参数三种。华东交通大学徐春辉制作华东交通大学徐春辉制作59 (1)通过累加器或寄存器传递参数)通过累加器或寄存器传递参数 在这种方式中,先把子程序需要的数据送入累加器先把子程序需要的数据送入累加器A或指定的或指定的工作寄存器中工作寄存器中,进入子程序后,再从这些相应的单元中取得数据,进行处理。子程序结束返回主程序时,也可用同样的方法把结果带回给主程序。该是方法的特点是:简单、快捷,但传递的参数个数不宜过多。华东交通大学徐春辉制作华东交通大学徐春辉制作60 【例5-11】实现两个8位的十六进制无符号数求
39、和的子程序。解:入口参数:(R3)=加数;(R4)=被加数。出口参数:(R3)=和的高字节;(R4)=和的低字节。HEXADD:MOV A,R3 ;取加数(在R3中)ADD A,R4 ;被加数(在R4中)加A JC PP1 MOV R3,#00H;结果小于255时,高字节R3内容为00H SJMP PP2PP1:MOV R3,#01H;结果大于255时,高字节R3内容为01HPP2:MOV R4,A ;结果的低字节在R4中 RET华东交通大学徐春辉制作华东交通大学徐春辉制作61 (2)通过指针寄存器传递参数)通过指针寄存器传递参数 当需要传递的数据量较大时,可以通过可以通过R0、R1及及DPT
40、R这些这些指针寄存器来传递待处理数据块的首地址指针寄存器来传递待处理数据块的首地址,而在子程序中再采用间接寻址的方式访问相应的数据。出口参数也可采用这种方式传递。【例5-12】将内部RAM 中两个4字节无符号整数相加,和的高字节由R0指向。数据采用小端模式存储(低地址中存放的是数据的低字节)。解:入口参数:(R0)=加数低字节地址;(R1)=被加数低字节地址。出口参数:(R0)=和的高字节起始地址。华东交通大学徐春辉制作华东交通大学徐春辉制作62NADD:MOV R7,#4 ;字节数4送计数器 CLR C ;NADD1:MOV A,R0 ;利用指针,取加数低字节 ADDC A,R1 ;利用指针
41、,被加数低字节加A MOV R0,A ;INC R0 INC R1 DJNZ R7,NADD1 DEC R0 ;调整指针,指向出口 RET 华东交通大学徐春辉制作华东交通大学徐春辉制作63 (3)利用堆栈传递参数)利用堆栈传递参数 在调用子程序之前,用用PUSH指令将子程序中所需数据压入堆指令将子程序中所需数据压入堆栈栈,执行子程序时利用该数据,子程序执行的结果又放于该堆栈单元。返回到主程序后再用POP指令从堆栈中弹出数据。【例5-13】将内部RAM中20H单元中的1个字节十六进制数转换为2位ASCII码,分别存放在21H、22H两个单元中。华东交通大学徐春辉制作华东交通大学徐春辉制作64 O
42、RG 1000HHEX DATA 20HASC DATA 21HMAIN:PUSH HEX;入口参数(预转换的数据(在低半字节)压栈 ACALL HEASC ;求低位十六进制数码的ASCII码 POP ASC ;弹出栈顶的转换结果(出口参数)于21H单元中 MOV A,HEX ;取预转换的数据 SWAP A ;高位十六进制数码送低4位 PUSH ACC ;入口参数压栈 ACALL HEASC ;求高位十六进制数码的ASCII码 POP ASC+1 ;弹出栈顶的转换结果于22H中 SJMP$华东交通大学徐春辉制作华东交通大学徐春辉制作65HEASC:DEC SP DEC SP ;入口参数地址送S
43、P POP ACC ;入口参数送A ANL A,#0FH ;取出入口参数低4位 ADD A,#07H ;地址调整 MOVC A,A+PC ;查表 POP ACC INC SP INC SP RET ASCTAB:DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46H END华东交通大学徐春辉制作华东交通大学徐春辉制作665.3 515.3 51系列单片机汇编语言实用程序设计举例系列单片机汇编语言实用程序设计举例 5.3.1 查表程序设计查表程序设计 所谓所谓查表,查表,就是根据自变量x的值在表格中寻找y,使y=
44、f(x)。在单片机应用系统中,查表程序是一种常用的程序。利用它能避免进行复杂的运算或转换过程,可完成可完成数据补偿、修正、计算、转换等各种功能,具有程序简单、执行速度快等优点优点。查表程序编制的关键在于关键在于,首先首先要根据变量间的数量关系建立一个表格,并将其存放在程序存储器中,然后然后利用51单片机指令系统所提供的查表指令完成由自变量的值获取函数值的操作。华东交通大学徐春辉制作华东交通大学徐春辉制作67 51单片机指令系统所提供的查表指令有如下两条:查表指令有如下两条:MOVC A,A+DPTRMOVC A,A+PC 利用这两条指令都可实现查表功能,但各有特点各有特点:华东交通大学徐春辉制
45、作华东交通大学徐春辉制作68 第一第一条指令条指令使用DPTR作为基地址查表,比较简单、易懂,且表格可以设在64KB程序存储器空间内的任何地方。可通过三步操作三步操作来完成:(1)将所查表格的首地址存入DPTR数据指针寄存器。(2)将所查表格的项数(索引值,即在表中的位置是第几项)送累加器A。(3)执行查表指令MOVC A,A+DPTR进行读数,查表结果送回累加器A。对于较短的表格,可使用第二条指令查表。华东交通大学徐春辉制作华东交通大学徐春辉制作69 第二第二条指令条指令使用PC作为基地址查表,查表原理和第一条的类同,只是操作有所不同,也可分为三步:(1)将所查表格的项数(索引值)送累加器A
46、,在MOVC A,A+PC指令之前先写上一条ADD A,#data指令,data的值待定(目的是使索引值索引值+data+PC=索引值索引值+表的首地址表的首地址)。(2)计算从MOVC A,A+PC指令执行后的地址到所查表的首地址之间的距离(以字节数表示),用这个计算结果取代加法指令中的data,作为A的调整量。(3)执行查表指令MOVC A,A+PC进行查表,查表结果送回累加器A。华东交通大学徐春辉制作华东交通大学徐春辉制作70 【例5-14】将一个16进制数码0F(R0的低4位)转换成相应的ASCII码,存放到原单元。解:数字09对应的ASCII码为31H39H,字母AF对应的ASCII
47、码为41H 46H。如果采用分支程序结构,程序较复杂,采用查表程序,可以使程序大大简化。方法1:采用MOVC A,A+DPTR指令查表,程序如下:ORG 2000H MOV DPTR,#TAB ;表格首地址送DPTR MOV A,R0 ;取索引值 ANL A,#0FH ;保留低4位 MOVC A,A+DPTR ;查表求ASCII码 MOV R0,A SJMP$TAB:DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46H END华东交通大学徐春辉制作华东交通大学徐春辉制作71 方法2:采用MOVC A,A+PC
48、指令查表。程序如下:地址 ORG 2000H2000H MOV A,R0 ;取索引值2001H ANL A,#0FH2003H ADD A,#03H ;对A调整2005H MOVC A,A+PC ;查表2006H MOV R0,A2007H SJMP$2009H TAB:DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46H华东交通大学徐春辉制作华东交通大学徐春辉制作72 通过实例看出:第一种方法使用DPTR作为基地址查表,比较简单易懂,且表格可以设在64KB程序存储器空间内的任何地方。任何地方。第二种方法使用
49、PC作为基地址查表,优点是预处理较少且节省了资源未使用DPTR寄存器,所以在子程序中也不必保护DPTR的原先值;缺点在于要计算调整值,且所查表格只能存放在查表指令地址之后的256个单元以内个单元以内,表格的长度及所在的存储空间都受到了限制。华东交通大学徐春辉制作华东交通大学徐春辉制作73【例5-15】在一个以AT89S51为核心的温度控制器中,温度传感器输出的电压与温度为非线性关系,传感器输出的电压已由A/D转换为10位二进制数(占2个字节)。已根据测得的不同温度下的电压值数据构成一个表,表中放温度值y,而x为电压值数据。设测得的电压值x已存入R6R7中,根据电压值x,查找对应的温度值y,仍放
50、入R6R7中。本例的x和y均为双字节无符号数。华东交通大学徐春辉制作华东交通大学徐春辉制作74LTB2:MOV DPTR,#TAB2 ;表首地址送DPTR MOV A,R7 ;(R6R7)2,也即(x2)CLR C RLC A MOV R7,A XCH A,R6 RLC A XCH R6,A ADD A,DPL;表首地址+(x2)(DPTR)MOV DPL,A MOV A,DPH ADDC A,R6 MOV DPH,A ;直接算得所查数据第一个字节的地址 CLR A MOVC A,A+DPTR ;查表得温度值高位字节 华东交通大学徐春辉制作华东交通大学徐春辉制作75 MOV R6,A ;存放高