第4章_MCS-51汇编语言程序设计-2012.ppt_第1页
第4章_MCS-51汇编语言程序设计-2012.ppt_第2页
第4章_MCS-51汇编语言程序设计-2012.ppt_第3页
第4章_MCS-51汇编语言程序设计-2012.ppt_第4页
第4章_MCS-51汇编语言程序设计-2012.ppt_第5页
已阅读5页,还剩114页未读 继续免费阅读

下载本文档

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

文档简介

1、第4章 MCS-51汇编语言程序设计,汇编语言是面向机器硬件的语言,要求程序设计者对MCS-51单片机具有很好的“软、硬结合”的功底。 本章介绍程序设计的基本知识及如何使用汇编语言来进行基本的程序设计。 4.1 汇编语言程序设计概述 4.2 汇编语言程序的汇编 4.3 汇编语言实用程序设计 4.3.1 汇编语言程序设计的基本原则 4.3.2 汇编语言程序设计的典型案例,4.1 汇编语言程序设计概述,4.1.1 机器语言、汇编语言和高级语言 用于程序设计的语言基本上分为3种:机器语言、汇编语言和高级语言。 1.机器语言 二进制代码表示的指令、数字和符号简称为机器语言不易懂,难记忆,易出错。,2汇

2、编语言 英文助记符表示的指令称为符号语言或汇编语言 将汇编语言程序转换成为二进制代码表示的机器语言程序称为汇编程序 经汇编程序“汇编(翻译)”得到的机器语言程序称为目标程序,原来的汇编语言程序称为源程序。 汇编语言特点: 面向机器的语言,程序设计员须对MCS-51的硬件有相当深入的了解。 助记符指令和机器指令一一对应,用汇编语言编写的程序效率高,占用存储空间小,运行速度快,用汇编语言能编写出最优化的程序。 汇编语言程序能直接管理和控制硬件设备(功能部件),它能处理中断,也能直接访问存储器及I/O接口电路。 汇编语言和机器语言都脱离不开具体机器的硬件,均是面向“机器”的语言,缺乏通用性。,3高级

3、语言 不受具体机器的限制,使用了许多数学公式和数学计算上的习惯用语,非常擅长于科学计算。常用的如BASIC、FORTRAN以及C语言等。 高级语言优点:通用性强,直观、易懂、易学,可读性好。 使用C语言(C51)、PL/M语言来进行MCS-51的应用程序设计。对于程序的空间和时间要求很高的场合,汇编语言仍是必不可缺的。 C语言和汇编语言混合编程 在很多需要直接控制硬件的应用场合,则更是非用汇编语言不可。使用汇编语言编程,是单片机程序设计的基本功之一,4 MCS-51单片机的编程语言,MCS-51单片机的编程语言可以是汇编语言也可以是高级语言(如C语言),高级语言编程快捷,但程序长,占用存储空间

4、大,执行慢;汇编语言产生的目标程序简短,占用存储空间小,执行快,能充分发挥计算机的硬件功能。无论是高级语言还是汇编语言,源程序都要转换成目标程序(机器语言)单片机才能执行。,支持写入单片机或仿真调试的目标程序有两种文件格式: BIN文件和 HEX文件, BIN文件是由编译器生成的二进制文件,是程序的机器码, HEX文件是由INTER公司定义的一种格式,这种格式包括地址、数据和校验码,并用ASCII码来存储,可供显示和打印。HEX文件需通过符号转换程序OHS51进行转换 两种语言的操作过程见图3-1。,连接/定位器 L51,汇编语言 源程序,汇编器A51,符号转换程序OHS51,绝对地址目标程序

5、 .BIN,C语言程序,浮动地址目标程序,编译器C51,HEX,图 4-1 两种语言源程序转换成目标程序,(一)汇编语言的种类 两种基本类型:指令语句和伪指令语句 (1)指令语句 已在第3章介绍 每一条指令语句在汇编时都产生一个指令代码机器代码 (2)伪指令语句 是为汇编服务的。在汇编时没有机器代码与之对应。,4.1.2 汇编语言语句的种类和格式,MCS-51的汇编语言的四分段格式如下: 标号字段 操作码字段 操作数字段 注释字段 规则: (1)标号字段和操作字码段之间要有冒号“:”相隔; (2)操作码字段和操作数字段间的分界符是空格; (3)双操作数之间用逗号相隔; (4)操作数字段和注释字

6、段之间的分界符用分号“;”相隔。 操作码字段为必选项,其余各段为任选项。,(二)汇编语言的格式与规则,例4-1 下面是一段汇编语言程序的四分段书写格式 标号字段 操作码字段 操作数字段 注释字段 START: MOV A,#00H ;0A MOV R1,#10 ;10R1 MOV R2,#00000011B ;3R2 LOOP:ADD A,R2 ;(A)+(R2)A DJNZ R1,LOOP;R1内容减1不 为零,则循环 NOP HERE: SJMP HERE 基本语法规则: 1标号字段 是语句所在地址的标志符号 (1) 标号后边必须跟以冒号“:” (2) 由18个ASCII字符组成 (3)

7、同一标号在一个程序中只能定义一次 (4) 不能使用汇编语言已经定义的符号作为标号 2操作码字段 是汇编语言指令中唯一不能空缺的部分。汇编程序就是根据这一字段来生成机器代码的。,3操作数字段 通常有单操作数、双操作数和无操作数三种情况。如果是双操作数,则操作数之间,要以逗号隔开。 (1)十六进制、二进制和十进制形式的操作数表示 采用十六进制形式来表示 ,某些特殊场合才采用二进制或十进制的表示形式 。 十六进制,后缀“H” ; 二进制,后缀“B” 。 十进制,后缀“D”,也可省略。 若十六进制的操作数以字符AF中的某个开头时,则需在它前面加一个 “0”,以便在汇编时把它和字符AF区别开来。,(2)

8、工作寄存器和特殊功能寄存器的表示 采用工作寄存器和特殊功能寄存器的代号来表示,也可用其地址来表示。例如,累加器可用A(或Acc)表示。也可用0E0H来表示,0E0H为累加器A的地址。 (3)美元符号$的使用 用于表示该转移指令操作码所在的地址。例如,如下指令: JNB F0, $ 与如下指令是等价的: HERE:JNB F0,HERE 再如: HERE:SJMP HERE 可写为: SJMP $,4注释字段 必须以分号“;”开头,换行书写,但必须注意也要以分号“;”开头。 汇编时,注释字段不会产生机器代码。,在MCS-51 汇编语言源程序中应有向汇编程序发出的指示信息,告诉它如何完成汇编工作,

9、这是通过使用伪指令来实现的。 也称为汇编程序控制命令。只有在汇编前的源程序中才有伪指令。经过汇编得到目标程序(机器代码)后,伪指令已无存在的必要,所以“伪”体现在汇编时,伪指令没有相应的机器代码产生。,4.1.3 伪指令,常用的伪指令: 1.ORG(ORiGin)汇编起始地址命令 在汇编语言源程序的开始,通常都用一条ORG伪指令来实现规定程序的起始地址。如不用ORG规定,则汇编得到的目标程序将从0000H开始。例如: ORG 2000H START:MOV A,#00H 规定标号START代表地址为2000H开始。 在一个源程序中,可多次使用ORG指令,来规定不同的程序段的起始地址。但是,地址

10、必须由小到大排列,地址不能交叉、重叠。例如: ORG 2000H ORG 2500H ORG 3000H ,2. END(END of assembly)汇编终止命令 汇编语言源程序的结束标志,用于终止源程序的汇编工作。在整个源程序中只能有一条END命令,且位于程序的最后。 3DB(Define Byte)定义字节命令 在程序存储器的连续单元中定义字节数据。 ORG 2000H DB 30H,40H,24,“C”,“B” 汇编后: (2000H)=30H (2001H)=40H (2002H)=18H(10进制数24) (2003H)=43H(字符“C”的ASCII码) (2004H)=42H

11、(字符“B”的ASCII码) DB功能是从指定单元开始定义(存储)若干个字节,10进制数自然转换成16进制数,字母按ASCII码存储。,4DW(Define Word)定义数据字命令 从指定的地址开始,在程序存储器的连续单元中定义16位的数据字。例如: ORG 2000H DW 1246H,7BH,10 汇编后: (2000H)=12H;第1个字 (2001H)=46H (2002H)=00H;第2个字 (2003H)=7BH (2004H)=00H;第3个字(2005H)=0AH (2005H)=0AH,5EQU(EQUate)赋值命令 用于给标号赋值。赋值以后,其标号值在整个程序有效。例如

12、: TEST EQU 2000H 表示标号TEST=2000H,在汇编时,凡是遇到标号TEST时,均以2000H来代替。,6. BIT位定义(赋值)命令 标号 BIT 位地址 作用: 同EQU指令,不过定义的是位操作地址。 例如 AIC BIT P1.1。,4.1.4 汇编语言程序设计步骤,(一)嵌入式系统的设计方法 1、确定方案和计算方法(算法:乒乓控制;连续控制;PID控制;线性最优控制;非线性控制等) 2、硬件系统设计(确定应用系统的硬件配置、性能指标) 3、软件系统设计(确定控制算法,合理分配存储器单元和I/O接口地址,编制源程序) 4、制作电路板,系统调试。,(二)汇编语言程序设计步

13、骤 (1)分析问题,确定算法 (2)根据算法,画出程序框图 (3)分配内存工作区及有关端口地址 (4)编写程序 养成在程序的适当位置上加上注释的好习惯。 (5)上机调试 编写完毕的程序,必须“汇编”成机器代码,才能调试和运行,调试与硬件有关程序还要借助于仿真开发工具并与硬件连接。,汇编语言源程序 “翻译”成机器代码(指令代码)的过程称为“汇编”。汇编可分为手工汇编和机器汇编两类: 4.2.1 手工汇编 人工查表翻译指令。但遇到的相对转移指令的偏移量的计算,要根据转移的目标地址计算偏移量,不但麻烦,且容易出错。,4.2 汇编语言源程序的汇编,4.2.2 机器汇编 用编辑软件进行源程序的编辑。编辑

14、完成后,生成一个ASCII码文件,扩展名为“.ASM”。然后在微计算机上运行汇编程序,把汇编语言源程序翻译成机器代码。 交叉汇编汇编后的机器代码是在另一台计算机(这里是单片机)上运行。 MCS-51单片机的应用程序的完成,应经过三个步骤; (1)在微计算机上,运行编辑程序进行源程序的输入 和编辑; (2)对源程序进行交叉汇编得到机器代码; (3)通过微计算机的串行口(或并行口)把机器代码传送到用户样机(或在线仿真器)进行程序的调试和运行。,第(1)步,只需在微计算机上使用通用的编辑软件即可完成。 第(2)步的交叉汇编所用的汇编程序可在购买单片机的仿真开发工具时,由厂商提供。 第(3)步骤的实现

15、要借助于单片机仿真开发工具进行。 反汇编分析现成产品的程序,要将二进制的机器代码语言程序翻译成汇编语言源程序。 例4-2 下面是一段源程序的汇编结果,读者可通过查第3章的表3-3至表3-7 ,进行手工汇编,来验证下面的汇编结果是否正确。 见表4-1(P75),4.3 汇编语言实用程序设计,4.3.0 汇编语言程序的基本原则 采用结构化、模块化设计原则 汇编语言程序的基本结构: 顺序结构 分支结构 循环结构 汇编语言程序的基本模块: 子程序 中断服务子程序,(1)汇编语言程序的基本结构,1)顺序结构 顺序程序(简单程序),程序走向只有一条路径 关键指令-查表 : MOVCA, A+DPTR,2)

16、分支结构,由条件转移指令构成程序判断框部分,形成分支结构。 为单分支程序和多分支散转程序两大类。 单分支程序 一个判断决策框,两种分支结构图。,关键指令-比较: CJNEA, direct, rel CJNEA, #data, rel CJNERn, #data, rel CJNERi, #data, rel,3)循环结构,当程序中的某些指令需要反复执行多次时,采用循环程序的方式,这样会使程序缩短,节省存储单元(并不节省执行时间)。 循环次数的控制,有两种控制方式: 第一种方法 先判断后处理即先判断满不满足循环条件,如不满足,就不循环,多以循环条件控制。 第二种方法 先处理后判断,即循环执行一

17、遍后,下一轮还需不需要进行,多以计循环次数控制。 循环可以有单重循环和多重循环,在多重循环中,内外循环不能交叉,也不允许外循环跳入内循环。,关键指令-减1比较: DJNZRn, rel DJNZdirect, rel,第一种方法:先判断后处理,第二种方法:先处理后判断,(2)单片机应用系统程序设计基本思路,引言: 教材中的例子都是从实际应用程序中提取出来的核心部分,程序较小,且只针对单一任务。而实际工程项目是复杂多样的,一般有多个任务要进行处理。如何处理? 对策: 拿到工程项目后,首先要对任务进行分解,分解的目标是每个单一任务,都可以用教材上的例子来解决。 对每个单一任务,都将其编写成一个独立

18、的子程序。 编写合适的主程序,将各个单一任务有机地连接起来,完成总体设计要求。 对于实际工程项目而言,主程序的总体结构一般为循环结构。与PLC类似。,(3)单片机应用系统主程序的基本结构,任何一个单片机系统程序,无论它有多大,总是有终点的且一定是从工作起点到终点的无限循环结构,这是所有单片机系统的共性。系统再复杂,无非是分支多、任务多且相互交错。 复杂系统中的“复杂”是相对的 ,不同的人对其看法是不同的。但是,采用合理的主程序结构,可以达到事半功倍的效果。 单片机主程序的结构大致可以分为一下几种: 过程控制结构 时间触发结构 事件触发结构,1)过程控制结构-(洗衣机),工业生产和制造行业等生产

19、流水线,多为工作流程固定模式。其控制系统的主程序要按工作流程顺序执行,当全部工作执行完成后,返回到工作起点,重复执行主程序的主体部分,工作特点是一个过程自然过渡到另一个过程。 在此,任务标志的设置与清除的目的是控制任务流程的进程。即当任务1完成后,主程序清除任务1 的工作标志,同时设置任务2工作标志,然后调用任务2子程序,执行任务2 的功能,任务2子程序执行完成后,返回主程序,主程序清除任务2的工作标志,设置任务3工作标志,然后调用任务3子程序,以此类推。 简单系统不设置任务标志也可以实现,但是复杂系统一般要求设置相应的任务标志,不仅用于显示系统进程,也便于系统调试。,2)时间触发结构-(三相

20、功率的测量),有一类工程问题,要求对多个输入量(模拟或数字的)进行等间隔测量,即要求每次采样中每个被测量的时间间隔相等。初看这个问题需要多个定时器解决,但实际上是不可行的,因为系统中的定时器资源是有限的。进一步分析,这类问题是周期性的,程序每次运行的过程完全相同,即对每个量的采样在一次采样过程中的(相对)时刻是固定的。因此,只要保证每个周期中各项工作在时间上的稳定性,并按固定顺序依次进行,就可以保证采样结果中,每个被测量的间隔固定,并等于采样周期。 结论:这类工程问题可以用一个定时器控制周期,在每个周期内,按顺序进行采样,即可实现工程要求。如果被测量是时间的函数,则该被测量的时间分辨率即为采样

21、周期。 解决这类工程问题的主程序结构称为时间触发结构。,时间触发结构,主程序按照任务规定的时间进行周期性工作,周期时间可以由定时器产生,也可以由系统硬件产生;可以用中断法,也可以用查询法。一旦定时到,程序就进入本次工作周期,当周期工作执行完成后,返回主程序查询点,等待下一个工作周期的到来。 在此注意定时标志的设置与清除。可以由硬件自动设置与清除,也可以由软件设置与清除,详细分析参见定时器章节。 周期工作时间要小于定时时间,且要留有足够的余量,否则会影响系统测量精度。,3)事件触发结构-(键盘检测),事件触发结构与时间触发结构的不同点:主程序不是周期工作,而是由系统关注的随机事件的触发来启动系统

22、工作的。这类程序结构来源于对于某种系统的安全监测与保护的工程问题。主程序不停的检测事件(标志),一旦事件发生,立即进行事件处理(一般都很紧急),事件处理完毕后,返回主程序继续查询,系统主程序的基本结构的分析,上述3种程序结构中,过程控制结构是最基本、最常用的。实际工程项目往往是3种主程序结构的综合,即在过程控制结构中,每一过程的处理又可能用时间触发结构或事件触发结构。 再次强调:主程序的基本结构是一个循环结构。 为了简化问题,最好采用最简单的单循环结构,如果不能实现系统功能,则再考虑添加条件分支结构,多重循环结构等。 如果采用结构化,模块化的设计思路,采用多层次的子程序调用方式,则主程序一定可

23、以用一个简单的单循环结构实现。 无论是单一结构系统,还是综合结构系统,都要求系统有响应各种附加中断的能力,以便处理突发事件。,系统主程序设计案例分析实验14 冲击电流记录仪,任务要求: 设计一个冲击电流测量装置,实现对三相交流电流有效值的测量、显示,并自动记录电流有效值的最大值。用LED 显示测量结果和相序,用按键控制测量仪起停和显示相序。 硬件实现 8051系列8位单片机作为控制器, I/O端口连接外部设备。 三个电位器模拟三相电流的有效值, ADC0809实现模数转换, 6位LED显示结果, 双键控制。,PROTUES仿真电路,软件系统设计,1、软件系统总体设计方案及主程序流程图 本系统是

24、一个自动测量记录装置,且对于系统实时响应速度要求不是特别高,因此,主程序设计为循环查询方式。通过不断检测控制按键的状态,确定系统当前要执行的工作任务,并通过依次调用相应的子程序实现系统预设的功能。通过将系统任务合理分割,合理调用,可以满足系统实时性要求,利用控制按键,系统可以灵活地在各个任务之间切换。 主程序流程图见右图,2 子程序分析及其流程图,2.1电压测量子程序 电压测量子程序完成对3路电压信号的依次采集,并存储到指定单元,以供单片机对采集的数据进行处理。A/D转换采用查询等待方式。 其程序流程图如右图:,2.2按键检测子程序,按键检测子程序主要完成系统工作方式切换和显示数据通道切换。其

25、中用K1键可以依次改变数据通道(13)标志,从而可以进行显示通道切换,用K2键依次改变系统工作方式(实时测量(空)、最大值测量(H)、最大值测量结果显示(P)标志,从而可以切换系统工作方式。其中,70H存放的是选择通道的代码,71H存放的是选择系统工作方式的代码。 程序流程图如右图:,2.3 最大值更新子程序,最大值更新子程序主要完成的工作是分别将各个通道的最新电流测量值(放置于60H、61H、62H单元中)与其对应的电流最大值(放置于63H、64H、65H单元中)进行比较,并更新当前最大值。 其程序流程图如右图:,2.4 显示数据选择及BCD转换子程序,显示数据选择及BCD转换子程序主要功能

26、是依据系统当前工作状态,从指定通道的数据采集结果单元或最大值计算结果单元中取出需要显示的数据,并将二进制数分离成百位数,十位数和个位数分别存放在指定的显示缓存单元(73H,74H和75H)中, 其流程图如右图:,2.5显示子程序,显示子程序主要是将当前显示显示存储单元中的数据送LED显示。其程序流程图如下:,参考程序初始化,ALEADEQUP3.2 STADEQUP3.4 OEADEQUP3.5 EOCADEQUP3.3 ORG 0000H MOV A, #0H;初始化 MOV P2, A;关显示 MOV60H,A;AD0测量值 MOV61H,A;AD1测量值 MOV62H,A;AD2测量值

27、MOV63H,A;AD0最大值 MOV64H,A;AD1最大值 MOV65H,A;AD2最大值 MOV70H,#1;显示最高位 MOV71H,#10; MOV72H,#10; MOV73H,#2; MOV74H,#5; MOV75H,#6;显示最低位,注意:参数传递方式。本例采用直接地址访问内存单元方式,相当于C51中的全局变量。当然在C51中可以不采用绝对地址方式,而由编译系统自动安排变量存储地址。,主程序,MAIN:LCALL TEST;A/D LCALL KEY;键盘 MOV A,71H CJNE A,#11,MAIN2;H键按下,进入记录最大值状态 LCALL MAX;求最大值 MAI

28、N2:LCALL BCD;BCD转换 LCALL DISP;显示 LJMP MAIN,电压测量(A/D)子程序,; 一次测量数据3个,依次放入60H-62H单元中 ; TEST:MOV A,#0FCH MOV P3,A MOV R0,#60H ;转换值存放首址 MOV R7,#03H ;转换3次控制 MOV A,#0FFH MOV P1,A WAITT:CLR ALEAD ;A/D地址锁存 SETB ALEAD CLR ALEAD CLR STAD ;启动A/D SETB STAD CLR STAD WAIT: NOP JNB EOCAD,WAIT ;等A/D转换结束信号,SETB OEAD

29、;取A/D转换数据 MOV A,P1 MOV R0,A CLR OEAD INC R0 MOV A,P3 ;通道地址加1 ANL A,#03 INC A ORL A,#0FCH MOV P3,A CJNE A,#0FFH,TESTEND ;等3路A/D转换结束 TESTEND: JC WAITT MOV A,#0FCH ;结束恢复端口 MOV P3,A MOV A,#0FFH MOV P1,A RET,按键检测子程序,KEY: SETB P2.6 JNB P2.6, KEY1 SETB P2.7 JNB P2.7, KEY2 RET KEY1: LCALL DL10MS ;延时消抖 SETB

30、P2.6 JB P2.6, KOUT WAIT11: SETB P2.6 JNB P2.6, WAIT12 INC 70H MOV A,70H CJNE A,#04,KOUT MOV 70H,#01H KOUT: RET WAIT12: LCALL DISP ;键释放等待时显示用 AJMP WAIT11,KEY2: LCALL DL10MS ;延时消抖 SETB P2.7 JB P2.7, KOUT2 WAIT112: SETB P2.7 JNB P2.7, WAIT122 INC 71H MOV A,71H CJNE A,#13,KOUT2 MOV 71H,#10 ;关显示或显示H KOUT

31、2: RET WAIT122: LCALL DISP ;键释放等待时显示用 AJMP WAIT112,最大值更新子程序,MAX:MOVA,60H CJNEA,63H,NEQ1 AJMPNEXT1 NEQ1:JCNEXT1 MOV63H,60H NEXT1:MOVA,61H CJNEA,64H,NEQ2 AJMPNEXT2 NEQ2:JCNEXT2 MOV64H,61H NEXT2:MOVA,62H CJNEA,65H,NEQ3 AJMPNEXT3 NEQ3:JCNEXT3 MOV65H,62H NEXT3:RET,显示数据选择及BCD转换子程序,BCD:MOVA,71H CJNEA,#12,B

32、CD2 MOVA,#62H;P键按下,显示最大值 AJMPBCD3 BCD2:MOVA,#5FH;P键没按下,显示测量值 BCD3:MOVR0,#70H ADDA,R0 MOVR0, A MOVA,R0;二进制数送A MOVB, #100;100作为除数送入B DIVAB MOV73H, A;百位数送73H,余数在B中 MOVA, #10;分离十位和个位数 XCHA, B;余数送A,除数10在B中 DIVAB;分离出十位在A, 个位在B中 MOV74H, A;十位送74H MOVA, B MOV75H, A;个位送 RET,显示子程序,DISP:MOV R0, #70H; 字形码存放单元首地址

33、70H75H MOV R1, #20H;位码-最高位 MOVDPTR, #TABLE LP1:MOVA, #0 MOVP0, A MOVA,R1 MOVP2,A RRA MOVR1,A MOV A, R0 MOVCA, A+DPTR MOV P0, A INC R0 LCALL DELAY3; 短延时 CJNE R1,#80H, LP1 RET TABLE:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH, 6FH,00H,76H,73H,延时子程序,DL10MS:MOV R6,#0D0H ;10MS延时子程序 DL1: MOV R7,#19H DL2: DJNZ

34、R7,DL2 DJNZ R6,DL1 RET DELAY3: MOV R7,#0FFH ;延时一小段时间 DEL: NOP DJNZ R7,DEL RET END,实验14 冲击电流记录仪,一、子程序设计原则和应注意的问题 一种能完成某一特定任务的程序段。其资源要为所有调用程序共享。因此,子程序在结构上应具有独立性和通用性, 在编写子程序时应注意以下问题: 1子程序的入口地址,前必须有标号。 子程序的第一条指令的地址称为子程序的入口地址。 该指令前必须有标号。即调用指令中的addr16或者addr11 2主程序调用子程序是通过主程序中的调用指令来实现的。 两条子程序调用指令: (1)绝对调用指

35、令:ACALL addr11 ;子程序在当前指令的2K地址范围内 (2)长调用指令:LCALL addr16 ;子程序在64K程序存储空间任意位置,4.3.1 子程序的设计,汇编语言程序设计的典型案例,在编写子程序时应注意问题:,3注意设置堆栈指针和现场保护 调用子程序时,要把程序断点地址(调用指令执行后的下一条指令的地址)压入堆栈(双字节,堆栈指针加2)。子程序返回时执行RET指令时再把断点弹出堆栈送入PC指针。因此,在调用子程序时,必须保证堆栈数据的安全性,防止误更改。 同时为了提高编程效率,主程序和子程序都要要使用寄存器,因此也要用堆栈来进行现场保护与现场恢复。 因此,堆栈的使用必须要非

36、常清楚。 4最后一条指令必须是RET指令 功能是把堆栈中的断点地址弹出送入PC指针中,从而实现子程序返回后从主程序断点处继续执行主程序。 5子程序可以嵌套,即子程序可以调用子程序 但是,不能递归调用不能自己调用自己。,在编写子程序时应注意问题:,6在子程序调用时,还要注意参数传递的问题 调用子程序时(在LCALL前),主程序先把有关参数送到约定位置,子程序运行时,从约定位置得到这些参数。同样子程序结束前(在RET前),也把运算结果送到约定位置。返回主程序后,主程序从约定位置获得这些结果。 参数传递分入口参数和出口参数两类 入口参数是子程序运行时需要的原始参数。 出口参数是子程序执行后获得的结果

37、参数。,二、 子程序的基本结构 典型的子程序的基本结构如下: MAIN: ;MAIN为主程序入口标号 LCALL SUB;调用子程序SUB 子程序 SUB:PUSH PSW;现场保护 PUSH Acc POP Acc ;现场恢复,注意要先进后出 POP PSW RET;最后一条指令必须为RET,例题3-0改用子程序-A51版本,例3_0原题:将外部数据存储器的000EH和000FH单元的内容相换。 ORG 0000H MOV DPTR, #000EH ;DPTR=000EH, ;DPTR外存储器地址指针,首先指向低位地址 MOVX A, DPTR ; A=(000EH) MOV 20H, A

38、;(20H)=(000EH),暂存 INC DPTR ; DPTR=000FH MOVX A, DPTR ;A=(000FH) MOV DPTR, #000EH ; DPTR=000EH ; DPTR再次指向低位地址 MOVX DPTR, A ;(000EH)(000FH) MOV A, 20H ; A=(000FH) INC DPTR ; DPTR=000FH MOVX DPTR, A ; (000FH)(000EH) SJMP $ END,LT3_0_2,例题3-0改用子程序-A51版本,XCHC:PUSHACC PUSHDPH PUSHDPL MOV DPH,R1 MOVDPL,R2 M

39、OVX A, DPTR MOV R0, A MOV DPH,R3 MOVDPL,R4 MOVX A, DPTR MOV DPH,R1 MOVDPL,R2 MOVX DPTR, A MOV A, R0 MOV DPH,R3 MOVDPL,R4 MOVX DPTR, A POPDPL POPDPH POPACC RET END,参数传递单元设置为内部RAM的R1,R2;R3,R4单元。将其中存储的外部RAM地址(16位)的对应单元内容相互交换。R0为中间变量单元。 ORG 0000H MAIN: MOVR1,#0 MOVR2, #0EH MOVR3,#0 MOVR4, #0FH LCALLXCHX

40、 MOVR1,#0 MOVR2, #10H MOVR3,#0 MOVR4, #11H LCALLXCHX LJMPMAIN 注意:参数传递,采用R0R7方式,相当于C51中的局部变量。该子程序功能完成后,就可以释放存储空间,便于其他子程序使用R0R7单元。,LT3_0_22,例题3-0改用子程序-C51版本,例3_0原题:外部RAM的000EH单元和000FH单元的内容交换,采用绝对地址访问方法。C语言程序如下: # include main( ) char c ; for(; ;) c=XBYTE14; XBYTE14=XBYTE15; XBYTE15=c ; ,LT3_0_c,例题3_0

41、改用子程序,C语言程序如下: #include void xchx(m,n) unsigned int m,n; char c; c=XBYTEm; XBYTEm=XBYTEn; XBYTEn=c; main( ) for(; ;) xchx(14,15); xchx(16,17); ,LT3_0_c2,注意:参数传递,反汇编, 看m,n传递参数,例4-0: 将实验1 二进制到BCD转换程序改为子程序模式,实验内容 :将给定的一个单字节二进制数(存放在R2中),转换成非压缩的二十进制(BCD)码,并存放到R3R4R5中。 单字节二进制数在0255之间,设单字节数在累加器A中,转换结果的百位数放

42、在R3中,十位数和个位数则放入A中。 转换原理,把二进制数除以1000、100、10等10的各次幂,所得的商即为千、百、十位数,余数为个位数。 将原程序改为子程序模式,并将原始数据由P0口输入,结果由P1,P2,P3口输出。 注意参数传递。,程序清单实验指导书提供,;NAME T1_1_BCD ORG0000H BCD1:MOVA, R2;二进制数送A MOVB, #100;100作为除数送入B DIVAB MOVR3, A;百位数送R3,余数在B中 MOVA, #10;分离十位和个位数 XCHA, B;余数送A,除数10在B中 DIVAB;分离出十位在A, 个位在B中 MOVR4, A;十位

43、送R3 MOVA, B MOVR5, A;个位送R4 SJMP$;停机(死循环) END,子程序模式右侧注意参数传递,;NAME T1_1_BCD ORG0000H BCD1:MOVA, R2 MOVB, #100 DIVABMOVR3, AMOVA, #10XCHA, BDIVAB MOVR4, A MOVA, B MOVR5, A SJMP$;停机 END,ORG0000H MR:MOVP0,0#FFH NOP MOVR2,P0;输入参数 LCALLBCD1 MOVP1,R3;输出参数 MOVP2,R4;输出参数 MOVP3,R5;输出参数 SJMPMR NOP BCD1:MOVA, R2

44、;子程序 MOVB, #100 DIVABMOVR3, AMOVA, #10XCHA, B DIVAB MOVR4, A MOVA, B MOVR5, A RET;子程序返回 END,(星研演示LT4_0_1),(星研演示LT4_0_2),习题3-10分析,为了星研仿真,添加了头尾两条伪指令 ORG 0000H ;原题 POP DPH;注意,是出栈 POP DPL MOV DPTR,#4000H;双字节查表程序 RL A MOV B,A MOVC A,A+DPTR PUSH ACC MOV A,B INC A MOVC A,A+DPTR PUSH ACC RET ;返回时出错,因为(5030H

45、)无程序。 ORG 4000H DB 10H,80H,30H,50H,30H,50H END,为修正原题运行错误,在5030H添加程序, ORG 0000H POPDPH POPDPL MOVDPTR,#4000H ;双字节查表程序 RLA MOVB,A MOVCA,A+DPTR PUSHACC MOVA,B INCA MOVCA,A+DPTR PUSHACC RET ORG4000H DB10H,80H,30H,50H,30H,50H ORG5030H NOP;空操作 SJMP$;死循环 END,(星研演示XT3_10_1),问题:从表中查到的是什么数据?或查到的数据用来做什么?,(星研演示

46、XT3_10_0),条件: (A)=02H, (SP)=52H, (51H)=FFH, (52H)=FFH,习题3-10分析续子程序与返回,ORG 0000H NOP LCALL ZCX NOP ;子程序调用完成后的程序返回点 NOP SJMP$ ZCX: POP DPH;注意,是出栈。 POP DPL MOV DPTR,#4000H ;双字节查表程序 RL A MOV B,A MOVC A,A+DPTR PUSH ACC MOV A,B INC A MOVC A,A+DPTR PUSH ACC RET ORG 4000H DB 10H,80H,30H,50H,30H,50H ORG 5030

47、H NOP ;空操作 SJMP $;死循环 END,子程序中的正常堆栈操作是先压栈后出栈,且压栈与出栈指令成对出现,这样,子程序在执行完后会返回子程序调用指令的下一条指令。 本例是先出栈后压栈,实际上已经破坏了栈顶保存的PC值,因此子程序返回时,将回到用户修改的PC地址。 改变压栈、出栈顺序或者直接去掉子程序中的堆栈操作,则子程序执行结束后会返回正常位置。,给出完整的子程序调用与返回,展示PC修改的后果,(星研演示XT3_10_2),习题3-10分析续子程序与返回,ORG 0000H MOV A, #02 ;输入参数 LCALL ZCX NOP ;子程序调用后正常的程序返回点 SJMP $ Z

48、CX: POP DPH;注意,是出栈。 POP DPL MOV DPTR,#4000H;双字节查表程序 RL A MOV B,A MOVC A,A+DPTR PUSH ACC MOV A,B INC A MOVC A,A+DPTR PUSH ACC RET ORG 4000H DB 10H,80H,20H,70H,30H,50H,ORG 5030H NOP ;空操作 SJMP $;死循环 ORG 7020H NOP ;空操作 SJMP $;死循环 ORG 8010H NOP ;空操作 SJMP $;死循环 END 注意:改变输入参数,02。观察程序走向。 为了便于观察,修改了数据表内容,数据补

49、偿、修正、计算、转换等各种功能,具有程序简单、执行速度快等优点。 查表就是根据自变量x,在表格中寻找y,使y=f(x)。 执行查表指令时,发出读程序存储器选通脉冲/PSEN。在MCS-51的指令系统中,给用户提供了两条极为有用的查表指令: MOVC A,A+DPTR MOVC A,A+PC 指令“MOVC A,A+DPTR”完成把A中的内容作为一个无符号数与DPTR中的内容相加,所得结果为某一程序存储单元的地址,然后把该地址单元中的内容送到累加器A中。 指令“MOVC A,A+PC”以PC作为基址寄存器,PC的内容和A的内容作为无符号数,相加后所得的数作为某一程序存储器单元的地址,根据地址取出

50、程序存储器相应单元中的内容送到累加器A中。指令执行完,PC的内容不发生变化,仍指向查表指令的下一条指令。优点在于预处理较少且不影响其它特殊功能寄存器的值,所以不必保护其它特殊功能寄存器的原先值。缺点在于该表格只能存放在这条指令的地址X3X2X1X0以下的00FFH之中。表格所在的程序空间受到了限制。,4.3.2 查表程序设计,汇编语言程序设计的典型案例,例4-3 子程序的功能为:根据累加器A中的数x(09之间)查x的平方表y,根据x的值查出相应的平方y。x和y均为单字节数。 地 址 子程序 Y3Y2Y1Y0 ADD A,#01H Y3Y2Y1Y0+2 MOVC A,A+PC Y3Y2Y1Y0+

51、3 RET Y3Y2Y1Y0+4 DB 00H,01H,04H,09H,10H DB 19H,24H,31H,40H,51H 第1条指令 ADD A,#01H 的作用是加上偏移量,可以根据A的内容查出X对应的平方。 MOVC A,+DPTR 这条指令的应用范围较为广泛,一般情况下,大多使用该指令,使用该指令时不必计算偏移量,使用该指令的优点是表格可以设在64K程序存储器空间内的任何地方,而不像 MOVC A,A+PC那样只设在PC下面的256个单元中,使用较方便。,例4-3-续 上面的程序可改成如下形式: PUSH DPH ;保存DPH PUSH DPL ;保存DPL MOV DPTR,#TA

52、B1 MOVC A,A+DPTR POP DPL ;恢复DPL POP DPH ;恢复DPH RET TAB1: DB 00H,01H,04H,09H,10H DB 19H,24H,31H,40H,51H 说明:DPTR是唯一个16位指针,资源紧张时,要注意用压栈出栈轮换使用,例4-3-续子程序版仿真,ORG0000H MAIN:MOV20H, P1;输入参数放入20H LCALLSEARCH NOP LJMPMAIN SEARCH:PUSH DPH ;保存DPH PUSH DPL ;保存DPL MOV DPTR, #TAB1 MOVA, 20H MOVC A, A+DPTR MOV21H,

53、A;输出参数放入21H POP DPL ;恢复DPL POP DPH ;恢复DPH RET TAB1: DB 00H, 01H, 04H, 09H, 10H DB 19H, 24H, 31H, 40H, 51H END 说明:查表子程序的输入参数用20H传递,输出参数用21H传递,(星研演示LT4_3_A),例4-3-续子程序版仿真_C语言,#include main() char x,*p; char code tab6=0,1,4,9,16,25; p=0 x20; x=tab*p; p+; *p=x; 注意:执行一条语句后,才可以修改内存单元(20H),改变输入参数。,(星研演示LT4_

54、3_C),#include #include main() char x,*p; char code tab6=0,1,4,9,16,25; x=tabP1; p=0 x21; *p=x; ,(星研演示LT4_3_C2),单字节到双字节查表程序 (星研仿真验证)?,【例4-4】有一巡回检测报警装置,需对16路(x)输入进行检测,每路有一个最大允许值(y),为双字节数。需根据测量的路数(x),查表找出对应该路的最大允许值(y),看输入值是否大于最大允许值,如果大于就报警。 取路数为 x(0 x 15),y为最大允许值,放在表格中。设进入查表程序前,假设路数 x 已放于 R2 中,查表后该路的最大

55、允许值 y 放于 R3 R4 中。查表的程序如下: TB3: MOV A,R2 ADDA,R2 ;(R2)*2(A) MOV R3,A ;保存指针 ADDA,#6 ;加偏移量 MOVC A,A+PC ;查第一字节 XCH A,R3 ADD A,#3 MOVC A,A+PC ;查第二字节 MOVR4,A RET TAB3: DW 1520,3721,42645,7580, 3483,32657 ;最大值表 DW 883,9943, 10000,40511,6758,8931 DW 4468,5871,13284,27808,TB3: MOV A,R2 ADDA,R2 ;(R2)*2(A) MOV

56、 R3,A ;保存指针 ADDA,#6 ;加偏移量 MOVC A,A+PC ;查第一字节 XCH A,R3 ADD A,#3 MOVC A,A+PC ;查第二字节 MOVR4,A RET TAB3: DW 1520,3721,42645,7580, 3483,32657 ;最大值表 DW 883,9943, 10000,40511,6758,8931 DW 4468,5871,13284,27808 表格长度不能超过256B,且表格只能存放于“MOVC A,A+PC”指令以下的256个单元中,如需把表格放在程序存储器空间的任何地方,应使用指令“ MOVC A,A+DPTR”。,(星研演示 LT

57、4_7_1),【例4-4-2】单字节到双字节查表程序 DPTR版本(子程序),ORG0000H MOVR2,#6 MAIN:LCALLTB4 SJMP$ TB4:MOVDPTR,#TAB3 MOV A,R2 ADD A,R2 ;(R2)*2(A) MOV R3,A ;保存指针 MOVC A,A+DPTR ;查第一字节 XCH A,R3 INC A MOVC A,A+DPTR ;第二字节 MOV R4,A RET TAB3: DW 1520H,3721H,4264H,7580H ;大值表 DW 3483H,3265H,7883H,9943H DW 1000H,4051H,6758H,8931H

58、DW 4468H,5871H,1328H,2780H END,(星研演示 LT4_7_2),例4-5 以AT89S51为核心的温度控制器,温度传感器输出的电压与温度为非线性关系,传感器输出的电压已由A/D转换为10位二进制数。测得的不同温度下的电压值数据构成一个表,表中温度值为y(双字节无符号数),x(双字节无符号数)为电压值数据。设测得电压值x放入R2R3中,根据电压值x,查找对应的温度值y,仍放入R2R3中。参考程序: LTB2:MOVDPTR,#TAB2 MOVA,R3 CLRC RLCA MOVR3,A XCHA,R2 RLCA XCHR2,A ADDA,DPL ;(R2R3)+(DPTR)(DPTR) MOVDPL,A MOVA,DPH ADDC A,R2 MOVDPH,A CLRA,双字节到双字节查表程序 (星研仿真验证)?,MOVC A,A+DPTR ;查第

温馨提示

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

评论

0/150

提交评论