【文档说明】第04章汇编语言程序设计课件.ppt,共(72)页,253.279 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-44748.html
以下为本文档部分文字说明:
第04章汇编语言程序设计§4-1汇编语言源程序►一、程序设计语言►二、汇编语言源程序格式►三、汇编语言伪指令►四、目标程序的生成一、程序设计语言(0)►1、机器语言:直接使用微处理机指令机器码编写程序的语言称作机器语言。►由于微处理机指令机器码(包括操作码和操作数)是以二进制形
式编码和存储的,所以用机器语言编写的程序有以下特点:►⑴计算机唯一能够直接识别、理解和执行的程序,因此所有用其他语言编写的程序最终都必须翻译成机器语言才能运行,所以机器语言程序也称目标程序;►⑵程序难
读、难写、难记、难交流、易出错,从而给程序的设计、调试、维护带来困难;►⑶不同微处理机其指令机器码不同,所以机器语言程序无通用性。一、程序设计语言(1)►2、汇编语言:►使用一套能够反映微处理机指令功能、特征的助记符来表述指令,并使用标号、序号等字符串来表达操作数,按一定格式编写程序的语言
称作汇编语言,其特征为:►⑴用汇编语言编写的汇编语言源程序必须经过手工或机器汇编成机器语言目标程序才能让计算机执行;►⑵由于一套助记符是由反映指令功能和特征的英文缩减,所以能够克服机器语言程序四难一易的缺点,给程序的设计、
调试、维护带来方便;►⑶未脱离“面向机器”的语言特点,程序通用性、可移植性差。一、程序设计语言(2)►3、高级语言:►按约定方式使用一些接近书写习惯的英语和数学表达形式编写程序的语言称作高级语言。其特点为:►⑴用高级语言编写的程序必须经特定的编译程序或解释程序翻译成机器语言才能让
计算机执行;►⑵与汇编语言一样能克服机器语言程序四难一易的缺点,给程序的设计、调试、维护带来方便;►⑶是“面向过程”的语言,使人们脱离了对机器本身的依赖,不但在编程时能集中精力在解决问题上,而且能使得编成的程序有一定通用性和较好的可移植性。一、程序设计语言(3)►4、汇编语言与高级语言的比较:►
⑴在功能相同条件下,汇编语言源程序生成的目标程序比高级语言源程序生成的目标程序占用存储单元少、执行速度快,一般有速度要求场所尽可能采用汇编语言编写源程序;►⑵为了获取目标程序而使用的工具,汇编程序比解释程序或编译程序简单要得多,所占存储单元约为后者的1/2至1/10;►⑶由于汇编语言的“面向机器”
性,能更合理地使用计算机硬件资源,所以在检测、控制、数据采集、通讯等场合比高级语言编程更方便、简捷。二、汇编语言源程序格式►汇编语言源程序由源语句组成,其语句结构四要素按书写次序依次为:►1、标号;►2、操作码;►3、操作数
;►4、注释。汇编语言源程序的源语句►标号操作码操作数注释三、汇编语言伪指令(0)►1、伪指令的作用:►伪指令用于控制汇编程序将汇编语言源程序汇编成机器语言目标程序的汇编过程,故可称其为“汇编命令”。►2、伪指令的特点:►⑴伪指令只
是控制汇编语言源程序变成机器语言目标程序的汇编过程的命令,不会使CPU产生任何特定操作;►⑵其种类的多少只与汇编程序本身的约定有关,与微处理机的种类无关;►⑶伪指令没有相应的机器代码。三、汇编语言伪指令(1)►⑴ORG伪
指令:定义起始地址伪指令►格式:ORG16位地址►A、ORG伪指令的前面可以有或无标号;►B、ORG伪指令的后面必须有操作数,即指定的起始地址。►⑵EQU伪指令:给标号赋值伪指令►格式:标号EQU已定义过的标号或数据►A、EQU伪指令的前面必须有标号段;►B、EQU伪指令的后面必须有常数
、地址、已定义过的标号等作操作数段;►注意:一个标号在源程序中只能赋值一次。三、汇编语言伪指令(2)►⑶DB(DCB)伪指令:定义字节内容►即以字节为单位依次存入存储单元中的伪指令►格式:(标号)DB1至8项的8位数据►A、DB伪指令的前面可以有标号,►也可以无标号
;►B、DB伪指令的后面必须有►汇编程序约定的1、4、8项8位数据;►C、多项数据必须以逗号分开。三、汇编语言伪指令(3)►⑷DW(DCW)伪指令:定义字内容►即以字为单位先低字节、后高字节依次存入存储单元中的伪指令(注意:也有先高字节、后低字节的约定)►格式:(标号)DW1至8项的1
6位数据►A、DW伪指令的前面可以有标号,►也可以无标号;►B、DW伪指令的后面必须有►汇编程序约定的1、4、8项16位数据;►C、多项数据必须以逗号分开。三、汇编语言伪指令(4)►⑸DS(DSB)伪指令:
定义以字节为单位►保留空间►格式:(标号)DS数值►A、DS伪指令的前面可以有标号,►也可以无标号;►B、DS伪指令的后面必须是一个常数项。►例:LEDH:DS10H;此处保留16个单元►⑹DSW伪指令:定义以字为单位保留空间►
格式:(标号)DSW数值►A、DSW伪指令的前面可以有标号,►也可以无标号;►B、DSW伪指令的后面必须是一个常数项。►例:LCDH:DSW10H;保留32个单元供缓冲三、汇编语言伪指令(5)►⑺bit伪指令:定义特定位►格式:标号bit位地址或符号►A、bit伪指令的前面必
须有标号;►B、bit伪指令的后面可以是被定义的位地址或位符号;►C、定义后即可用该标号代替指定的位。三、汇编语言伪指令(6)►⑻END伪指令:程序结束伪指令►格式:END(标号或地址)►A、END伪
指令后面可以有或无标号、地址,若有则汇编结束后即从该标号指定的地址开始执行程序;►B、END伪指令表示源程序的结束,汇编程序对其后面的内容将不再理睬。四、目标程序的生成►1、手工汇编:►对照汇编语言指令表,将汇编语言源程序正确翻译成机
器语言目标程序,注意多字节指令中的机器码次序。►2、机器汇编:►借助于PC机及汇编程序等工具将汇编语言源程序翻译成机器语言目标程序。►通常汇编语言源程序的文件扩展名为“.ASM”,汇编后生成扩展名为“.HEX”的十六进制机器码文件和扩展名为“.LST”的列表文件等。§4
-2汇编语言程序设计►一、汇编语言程序设计步骤►二、程序流程图►三、结构程序设计基本模块►四、子程序一、汇编语言程序设计步骤►1、根据实际问题抽象出数学模型;►2、结合所使用CPU特点确定解决问题的算法;►3、根据算法思路列出程序流程图;►4、分配寄存器、内存单元,组织数据;►5、按照流程图编写
程序;►6、手工或机器汇编后得到机器语言目标程序;►7、借助于开发工具调试和修改程序。二、程序流程图(1)►1、流程图的作用:►流程图是对程序执行过程的图解表示法,它往往比文字描述更为直观和有效。其最大特点为各个功能部分以时间为线索有机地联系起来。从时间顺序上看整个过程条理井然,所
以不仅在程序设计中使用,还广泛地使用在非计算机操作的其他场合。二、程序流程图(2)►2、流程图的符号:►最常用的流程图符号有以下几种:►⑴处理框图:表示数据处理、数据传送、输入/输出、某种功能等(矩形框)►⑵逻辑判断框图:有两个走向,根据条件判断决定程序的去向(棱形)►⑶子程序框图:表示调
用子程序(处理框图中的两端加两竖)►⑷起始与终止框图:表示程序的开始或结束(鼓形)►⑸连接点框图:表示程序的连接点,常用于不同页码中程序的连接(小圆)►⑹连接箭头符:表示程序的连接与走向(带箭头线条)图例常用流程图的符
号►⑴处理框图⑷起始与终止框图►⑵逻辑判断框图⑸连接点框图►⑶子程序框图⑹连接箭头符n返回二、程序流程图(3)►3、流程图的优缺点:►优点:►⑴通俗易理解,即使对于没有程序设计知识的人也能方便地读懂;►⑵流程图可粗可细,故可把设计分成若
干个子任务,根据对流程图的评价即能评价任务进展情况;►⑶流程图以时间顺序为线索表示操作过程,故有利于确定须修改的错误源;►⑷流程图除程序设计之外,还可广泛使用于其他领域。►缺点:►⑴没有对流程图本身查错与测试的简易方法;►⑵流程图只
能表示程序的组织结构,表示不了其数据结构;►⑶流程图对于硬件结构及定时问题没有帮助;►⑷复杂程序流程图往往很难设计,难度甚至超过设计程序的本身。三、结构程序设计基本模块(1)►结构程序设计的特点是采用单入口、单出口模块,基本模块有三
种:►1、顺序结构模块:►即一种线性结构的模块,模块中的指令语句或指令集将被顺序执行。►2、条件结构模块:►条件结构模块是根据某种条件选择程序走向的一种选择结构,它是分支结构的基础,是程序赋予计算机某种人工智能的重要手段。►条件结构模块中,借以判断条件的内容,主要是程序状态字PSW中的标志位
,其次也可以是编程者设定的特殊标志或程序运行结果等。►3、循环结构模块:►程序中,在某种条件下往往要求某一段程序重复执行多次,这时候可以采用循环结构。图例图例另外循环结构模块►循环结构模块包括三个部分
:►⑴循环主体:即要求重复执行的程序段,包括循环工作部分和循环控制部分;►⑵循环条件:即循环结束的条件,最常见的循环条件是计数循环,当循环一定次数后就结束循环,计数可以采用增或减方式;►⑶循环初态:即循环开始时的必要条件,包括循环工作部分的初态及循环条件部分的初态。例如多字节带进位加法循环时,
循环工作部分初态应清进位标志C并设置地址指针,字节计数器的初态可预置循环次数,再逐一减到0,也可以先清0,再逐一增加直到与循环次数相等时再结束循环。图例三、结构程序设计基本模块(2)►4、选择结构模块:►选择结构有时也称分支结构,虽不属于结构程序设计的基本模块,但它用得十分普遍
,以致可以作为结构程序设计的辅助结构模块。►5、结构程序设计的特点:►⑴只允许三种基本结构及少量辅助结构;►⑵结构可以嵌套到任意复杂的程度;►⑶每个模块只允许一个入口和一个出口。四、子程序(1)►1、什么是子程序?►编写汇编语言源程序时,把经常用到的一些程序段落编写成一个相对独立的程序,用到时可
以随意调用并能自动返回。►被调用的程序称作子程序;►调用子程序的程序称作主程序。►子程序的调用是汇编语言程序设计中的一种很重要的手段,微处理机指令系统中往往都设置有专门用于子程序调用和返回的指令。四、子程序(2)►2、子程序的操作过程:►调用
子程序的过程也像程序转移一样是通过修改程序计数器PC中的数值来实现的,它与一般程序转移过程的区别在于:子程序调用时,总是先将程序计数器PC的值压入堆栈中保护起来。由于子程序总是以RET指令结束,它将主程序调用时PC的值从堆栈弹回,从而使程序能够返回主程序的调用处。这种设计的实现
完全依赖于堆栈的先进后出特性,并须使返回主程序时的堆栈指针SP值与调用之时相等,否则将无法保证程序的正确返回。四、子程序(3)►3、子程序的编写要点:►⑴子程序的第1条语句必须要有标号,以便作为调用指令的调用名称;►⑵子程序必须以RET
指令结束,以便能够正确返回主程序;►⑶子程序应有操作功能说明,以便调用时参考;►⑷子程序应该注明入口条件,便于调用时设法给予满足;►⑸子程序应该标注出口条件,便于主程序的很好衔接。四、子程序(4)►4、子程序中数据保护
:►为了防止子程序中所使用的寄存器的内容被修改后对主程序的错误影响,应充分考虑到子程序执行过程中这些寄存器中内容的变化,这种变化有两种可能,一种是须带给主程序的操作结果,另一种是不能带给主程序、与主程序无关的中间结果。►对于与主程序无关
的中间结果若传递给主程序将使程序产生错误。因此,必须采取措施对主程序中所用到而子程序也必须使用的寄存器在调用子程序之时对其内容进行保护。►对于MCS-51CPU其子程序中数据保护方法通常有以下三种:►⑴利用四组工作寄存器互换的方法,使主程
序与子程序使用不同组别工作寄存器,从而可以保护工作寄存器R0~R7中的数据不受破坏;►⑵利用堆栈的先进后出特性,将主程序与子程序中均需使用的寄存器中内容在进入子程序时依次压入堆栈保护起来,返回主程序前再依次弹出恢复;►⑶
将主程序与子程序均需使用的寄存器中内容在刚进入子程序时暂用其它空闲寄存器寄存,返回主程序前取回。四、子程序(5)►5、子程序中参数传递:►被调用的子程序与调用的主程序之间有参数需要传递时,视须传递的参数量的多少分别
采用以下三种方法实现:►⑴参数量很少时,往往利用指定的寄存器进行;►例如:将一个字节压缩BCD码转换成2位ASCII码的子程序中,可指定:►R0中存放被转换的压缩BCD码作为入口条件;►R0中存放低位BCD码的ASCII码、R1
中存放高位BCD码的ASCII码为出口状态。►⑵参数量较少时,往往可利用堆栈来进行参数传递;►⑶参数量较多时,往往需开辟一个公共存储区域作为主程序与子程序的数据共享区域,此时,只需在主程序、子程序中分别指定数据区域的数据指针即可。§4-3汇
编语言程序设计实例►一、数据传送程序►二、数值运算程序►三、数码处理程序►四、数值处理程序►五、其它处理程序一、数据传送程序►例4-3-1:请编写将片内RAM中20H开始的8个单元中的数据传送到70H开始的单元之中的程序。►例4-3-2:请
编写将片内RAM区20H单元开始的16单元数据传送到片外RAM的4000H单元开始的存储单元中的程序。►例4-3-3:试编写将程序存储器区1800H单元开始的16字节数据传送到片内RAM区的60H为首地址单元中的程序。流
程程序程序程序二、数值运算程序►例4-3-4:请编写多字节无符号二进制数加法程序。被加数、加数分别存放在片内以ADR1、ADR2为首地址的RAM中,数据以低字节放低地址、高字节放高地址的规律依次存放,其字节数存放在工作寄存器R7中,加得的结果放回被加数原存放单元。►例4-3-5:
请编写16位数乘16位数的无符号数乘法子程序。►例4-3-6:请编写用查表法求片内RAM区60H单元中数的平方值,结果存入其后面二个单元中的程序。程序程序程序三、数码处理程序►例4-3-7:请编写将一个十六进制数据串转换为ASCII码的程序,该十六进制数据串存放于起始地址为ADR1的内存区
域中,转换后的结果存放到以ADR2为起始地址的内存区域中去,字节串的长度在工作寄存器R7中。►例4-3-8:请编写将累加器A中的ASCII码转换为16进制数后存放于数据存储器区1000H单元之中的程序,若A中ASCII码内容非
为16进制数,则该单元内容置FFH。►例4-3-9:若待转换的BCD码以非压缩BCD码形式存放在累加器A中,试用查表方式编写一位BCD码转换成ASCII码后结果仍在累加器A中的子程序。程序程序程序四、数值处理程序►例4-3-10:请编写在片外数据存储器区2000
H单元开始的32个字节中寻找最大值后存放到片内RAM的68H单元中的程序。►例4-3-11:请编写统计片外数据存储器区2000H单元开始的256单元中ASCII码字符A的个数的程序,统计数据存放在片内RAM的6FH单元中。►例4-3-12:请编写程
序,将片外RAM区1000H单元开始的30个短整数按正、负数分开存储,正数从30H单元开始存放,负数从40H单元开始存放,假设这些被使用单元已被清零。►例4-3-13:请编写将片内RAM区中30H~3AH单元中十一个字节数据按从大到小
规律排序的程序。►例4-3-14:请编写将片内RAM区30H~3AH单元中十一个已从大到小排序的字节数据去除1个最大值、去除1个最小值后再取平均值的数值滤波程序。若平均值大于等于100,则置7FH单元为全1,否则将该单元清零。程序程序程序程序程序五
、其它处理程序►例4-3-15:若MCS-51系统主频为12MHz,试编写延时1毫秒子程序。►例4-3-16:系统主频仍为12MHz,试编写延时1秒程序。►例4-3-17:编写根据面板上拨码开关从0~9的设置,转入TP0~TP9相应分支程序的程序,拨码开关的地址为8000H。程序程序程序本章总
结►1、汇编语言程序源语句的构成►2、汇编语言源程序中的伪指令►3、汇编语言源程序设计方法►4、子程序及其设计►5、汇编语言程序设计及调试C51简介►FranklinC51的数据类型C51简介►C51存储
类型和51系统存储空间的对应关系chardataval;//片内数据存储区00H-FFFHbitbdataflag;//片内位寻址区20H-2FHfloatidatax;//片内数据存储区,间接寻址方
法访问unsignedintpdatay;//片外数据存储区,用MOVX@R0访问unsignedcharxdataabc;//片外数据存储区,//用MOVX@DPTR访问C51简介►C51的数据存储模式及说明►#p
ragmalargeC51简介►常用的头文件►#include<math.h>►#include<reg51.h>►#include<stdio.h>►#include<string.h>►#include<stdlib.
h>►#include<absacc.h>C51简介►sbitCON=P1^0;►sbitSTATUS=P1^4;►voidDelay1ms(void)►{►TMOD=0x51;//T1:Counter,T0:Timer►T
R0=0,TF0=0,TH0=0x0fc,TL0=0x18;//65536-0x0fc18:1ms►TR0=1;►while(TF0==0);►TF0=0,TR0=0;►}►voidDelaynms(intnms)►{►registeri
nti;►for(i=0;i<nms;i++)Delay1ms();►}C51简介►voidmain(void)►{►STATUS=1;►for(;;){►Delaynms(1000);►CON=STATUS;►}►}
本章作业►4-4►4-6►4-9改为:x2.5+y►4-12例4-3-1程序流程►开始结束设置源数据指针设置目标地址指针设置循环次数次数到?获取源数据修正源地址指针传送到目标地址修正目标地址指针11
YN返回例4-3-1源程序清单►ORG0100H►MOVR0,#20H;源数据地址指针MOVR1,#70H;目标地址指针►MOVR7,#08H;取传送字节数LP:MOVA,@R0;取源数据►MOV@R1,A;数据传送到目标
地址INCR0;源数据地址指针+1INCR1;目标地址指针+1►DJNZR7,LP;未传送完则循环►NOP;结束返回例4-3-2源程序清单►解:用工作寄存器和数据指针分别作为源数据及目标地址的指针。ORG0200H►MOVR0,#20H;工作寄存器R0指向源数据首址►MOVDPTR,
#4000H;数据指针指向目标地址►MOVR7,#10H;取传送数据的字节数►MLP:MOVA,@R0;取源数据►MOVX@DPTR,A;送入目标地址►INCR0;修正源地址指针►INCDPTR;修正目标地址指针►DJNZR7,MLP;
未送完则循环►NOP;送完则结束返回例4-3-3源程序清单►解:数据指针和堆栈指针分别作为源数据地址和目标地址的指针。►ORG0300H►MOVR6,SP;暂存保护堆栈指针►MOVDPTR,#1800H;指针指向源数据首地址►MOVR0,#60H;R0指向
目标地址首地址►MOVR7,#10H;取传送数据的字节数►CLP:CLRA;清累加器►MOVCA,@A+DPTR;获取源数据►MOV@R0,A;存放数据到目标地址►INCDPTR;修正源地址指针►INCR0;修正目标地址指针►DJNZR7,CLP;未完成则循环►NOP;完成则结束
返回例4-3-4源程序清单►解:ADR1EQU40H;指定被加数存放首地址►ADR2EQU60H;指定加数存放首地址►ORG0030H►MOVR0,#ADR1;R0指向被加数首址►MOVR1,#ADR2;R1指向加数首地址►C
LRC;清进位标志为带进位相加作准备►LP:MOVA,@R0;取一个字节被加数►ADDCA,@R1;加上一个字节加数►MOV@R0,A;结果放回原地址►INCR0;修正被加数数据指针►INCR1;修正加数数据指针►DJNZR7,LP;是否加完未
完转移►NOP;做完则结束处可加断点返回例4-3-5源程序算法原理►子程序功能:16位×16位得到32位的积►子程序入口:被乘数a、b在工作寄存器R7、R6中,乘数c、d在R5、R4中►子程序出口:R0所指片内RAM单元为乘积高字节所使用资源:部
分乘积存放R3、R2中,进位位暂存R1中►算法:ab►×cd►bdHbdL►adHadL►bcHbcL►+acHacL►=MR3MR2MR1MR►用MUL指令分4次求积,按列求和,即可得到32位的乘积。例4-3-5源程序清单(1)►MUL1:MOV
A,R6;取被乘数低位b►MOVB,R4;取乘数低位d►MULAB;得到bdH和bdL►MOV@R0,A;结果bdL放到目标地址单元►MOVR3,B;暂存bdH►MOVA,R7;取被乘数高位a►MOVB,R4;取乘
数低位d►MULAB;得到adH和adL►ADDA,R3;得到adL+bdH►MOVR3,A;暂存adL+bdH►MOVA,B;将adH取入累加器A►ADDCA,#00H;adH加上进位标志C►MOVR2,A;暂存adH►MOVA,R6;取被乘数
低位b►MOVB,R5;取乘数高位c►MULAB;得到bcH和bcL►ADDA,R3;得到bcL+adL+bdH►INCR0;修正存放地址指针►MOV@R0,A;结果bcL+adL+bdH放目标地址单元例4-3-5源程序清单(2)►CLRR1;清进位标志暂存单元►MOVA,R2;将adH取入
累加器A►ADDCA,B;得到bcH+adH+“C”►MOVR2,A;暂存中间结果►JNCLAST;无进位时跳转►INCR1;有进位时暂存进位标志C►LAST:MOVA,R7;取被乘数高位a►MOVB,R5;取乘数高位c►MULAB;得到acH和acL►ADDA,R2;得到acL+bcH+
adH►INCR0;修正目标地址指针►MOV@R0,A;存放结果acL+bcH+adH到目标地址单元►MOVA,B;acH取入累加器A►ADDCA,R1;加上进位标志暂存结果►INCR0;修正目标地址指针►MOV
@R0,A;存结果acH到目标地址单元►RET;结束返回主程序返回例4-3-6源程序清单►ORG0400H►MOVA,60H;取源操作数►RLA;操作数左移1位即乘2►MOVR3,A;保护操作数乘2后的值►MOVDPTR,#TABM;指针指向平方值表首址►MOVCA,@A+DPTR;读
取平方值的低位结果►MOV61H,A;存放低位结果►MOVA,R3;重取操作数乘2后的值►INCA;指向其下一单元即高位►MOVCA,@A+DPTR;读取平方值的高位结果►MOV62H,A;存放高位结果►SJMP$
;表示程序结束的自循环►ORG1000H►TABM:►DB00H,00H,01H,00H,04H,00H,09H,00H►DB10H,00H,19H,00H,24H,00H,31H,00H►DB40H,00H,51H,00H,………………………
返回例4-3-7源程序清单(1)►‘1’-‘9;:+30H;’A’-’F’:+37H►ADR1EQU60H;定义十六进制数据串的起始地址►ADR2EQU20H;定义ASCII码结果存放起始地址►ORG0030H;指定程序
起始地址►MOVR0,#ADR1;R0指向十六进制数据►MOVR1,#ADR2;R1指向结果存放地址►HCAL0:MOVA,@R0;累加器A中取入一字节十六进制数►ANLA,#0FH;屏蔽高半字节,先转换低半字节►M
OVR2,A;暂存低半字节►ADDA,#0F6H;加246后有否进位判别是否大于10►MOVA,R2;取回低半字节十六进制数►JNCHCAL1;无进位即小于10,跳过下一条指令►ADDA,#07H;有进位须加7►HCAL1ADDA,#30H;加30H转换成ASCII码►MOV@R1,
A;存放转换结果的ASCII码例4-3-7源程序清单(2)►INCR1;修正结果存放地址指针►MOVA,@R0;重取该字节十六进制数►ANLA,#0F0H;屏蔽低半字节转换高半字节►SWAPA;高字节十六进制数放到低位►MOVR2,A;暂存高半字节内容►ADDA,
#0F6H;加246后有否进位判别是否大于10►MOVA,R2;取回高半字节十六进制数►JNCHCAL2;无进位即小于10,跳过下一条指令►ADDA,#07H;有进位须加7►HCAL2:ADDA,#30H;加30H转换成ASCII码►MOV@R1,A;存放转换
结果的ASCII码►INCR1;修正结果存放地址指针►INCR0;修正十六进制数据指针►DJNZR7,HCAL0;判是否完成转换,未结束转►NOP;结束,此处可设断点返回例4-3-8源程序清单(1)►解:MOVR7,A;保护源操作数►CLRC;为做减法而清进位标志►SUBBA,
#47H;是否非十六进制数►JCLP1;有借位即是十六进制数转移►SJMPLP4;非十六进制数转移►LP1:MOVA,R7;重取ASCII码►CLRC;为做减法而清进位标志►SUBBA,#41H;是否十六进制数的A至F►JCLP2;不是则转移►ADDA,#0AH
;是则加10即为十六进制数A至F►SJMPLP5;转出口存储例4-3-8源程序清单(2)►LP2:MOVA,R7;重取ASCII码►CLRC;为做减法而清进位标志►SUBBA,#3AH;是否十六进制数0至9等►JCLP3;是则转移►SJMPLP4;非十六进制数转移►LP3:MOVA,R7;重取AS
CII码►CLRC;为做减法而清进位标志►SUBBA,#30H;是否十六进制数的0至9►JNCLP5;是则转移►LP4:MOVA,#0FFH;不是则取FFH►LP5:MOVDPTR,#1000H;数据指针指向目标地址►MOVX@DP
TR,A;存储结果►SJMP$;表示程序结束的自循环返回例4-3-9源程序清单(1)►解:MCS-51查表方式可有远程查表和近程查表2种方式,分别以TABS1和TABS2表示:►TABS1MOVDPTR,#TAB►;
数据指针指向表格首地址►MOVCA,@A+DPTR►;查表得到对应的ASCII码►RET;返回主程序►TABDB30H;0的ASCII码►DB31H;1的ASCII码►∶►DB39H;9的ASCII码►以上为利用数据指针DPTR的远程查
表,其特点应为ASCII码表格可存放在64K程序存储器的任何位置上。例4-3-9源程序清单(2)►以下利用程序计数器PC的近程查表,其ASCII码表格必须紧跟在转换子程序的后面,即使子程序结束时有一条返回主程序的RET指令介在中间,也
必须修正累加器A中的内容以抵消其影响。子程序如下:►TABS2INCA;修正累加器A中内容抵消RET指令影响►MOVCA,@A+PC►;查表得到对应的ASCII码►②22RET;返回主程序►TAB:DB30H;0的ASCII码►DB31H;1的ASCII码►∶►
DB39H;9的ASCII码返回例4-3-10源程序清单►解:MOVDPTR,#2000H►;数据指针指向源数据首址►MOVR7,#1FH►;设置循环比较次数►MOVXA,@DPTR;取第一个操作数►MOV68H,A;设为最
大值保存到目标中►LOOP:INCDPTR;调整数据指针►MOVXA,@DPTR;取下一个操作数►CJNEA,68H,LOP►;取入数据是否比目标单元内容大►LOP:JCLP;否无须交换跳过下一指令►MOV68H,A►
;是,以累加器中内容取代目标单元内容►LP:DJNZR7,LOOP;循环控制►NOP;比较31次后程序结束返回例4-3-11源程序清单►解:MOVDPTR,#2000H►;数据指针指向源数据首址►MOVR7,#0H►;设置循环比较次
数►MOV6FH,#0H►;统计数据存放单元清零►SLP:MOVXA,@DPTR;取源操作数►CJNEA,#41H,SLP1►;取入数据是否是ASCII码A,不是跳转►INC6FH;是,统计数据存放单元
加1►SLP1:INCDPTR;修正指针指向下一单元►DJNZR7,SLP;循环控制►NOP;统计完成程序结束返回例4-3-12源程序清单►解:MOVDPTR,#1000H;数据指针指向源数据区首址►MOVR0,#30H;设置正数存放指针►MOVR1,#40H;设置负数存放指
针►MOVR7,#30;取分储操作次数FLP:MOVXA,@DPTR;取源操作数►JBACC.7,FLP1;是负数转移►MOV@R0,A;是正数转储►INCR0;修正正数据指针指向下一单元►SJMPFLP2;转循环控制FLP1:MOV@R1,A;转储负数►INCR1;修正负数据指针指向下一单元F
LP2:INCDPTR;修正源数据指针指向下一单元►DJNZR7,FLP;循环控制►NOP;分储完成程序结束返回例4-3-13源程序清单►解:MOVR7,#0AH;取数据比较遍数►L0:MOV40H,R7;取数据比较一遍的次数►MOVR0,#30H;源数据指针指
向数据首地址►MOVA,@R0;取第一个数据►L1:INCR0;修正数据指针►MOVR1,A;暂存数据►CLRC;为做减法而清借位标志►SUBBA,@R0;与下一单元数据相减比较►MOVA,R1;恢复数据►JNCL2;无借位无须交换
而转移►XCHA,@R0;有借位则2个存储单元内容经累加器交换►DECR0►XCHA,@R0►INCR0►L2:MOVA,@R0;重取数据准备下一轮比较►DJNZ40H,L1;一遍未比较完成转移►DJNZR7,L0;未全部比较完成则转移►NOP;比较
完成则程序结束返回例4-3-14源程序清单►解:MOVR0,#31H;数据指针指向有效数据首字节►MOVR7,#08H;9个有效数据需加8次►MOVB,#00H;结果和的高位清0►MOVA,@R0;取有效数据首位►LP0:INCR0;修正数据指针►ADDA,@R0;数据相加
►JNCLP1;无进位转移►INCB;有进位加到和的高位上►LP1:DJNZR7,LP0;未加完继续►MOVR7,A;暂存结果和的低位►MOVA,B;取结果高位用于比较►CLRC;为做减法而清进位标志►SUBBA,#03H;均值大于100时即和的高位须大于3►;9*100=900=
0384H►JNCLP2;高位大于3进而转去比较和的低位►SJMPLP3;转均值小于100的处理►LP2:MOVA,R7;取和的低位结果►SUBBA,#84H;均值大于100时和的低位须大于84H►JCLP3;否,转均值小于100的处理►MOV7FH,#0
FFH;是,置7FH单元为全1►SJMPLP4;转结束出口►LP3:MOV7FH,#00H;均值小于100,清7FH单元为全0►LP4:NOP;程序结束的出口返回例4-3-15源程序清单►DY1:PUSH30H;2►MOV30H,#N;1,N=2
48=F8H►DL:NOP;1►NOP;1►DJNZ30H,DL;2►POP30H;2►RET;2►延迟时间计算:若系统主频为12MHz,则每个机器周期为1μS,所以:►2+1+(1+1+2)N+2+2=1000μS►4N=993μS►若取N=248则4×248=992
,即子程序真正延时为999μS,有千分之一误差。返回例4-3-16源程序清单►解:若直接调用延时1MS子程序须调用1000次,超过一个8位寄存器的负荷,可用子程序嵌套方式来编写,先编写100MS子程序,再调用它
10次。►ORG0100H►MOVR6,#10;设定调用次数►LP:LCALLDY100;调用100MS延时►DJNZR6,LP;1秒未到循环►NOP;1秒到则执行以下其他程序►∶►ORG1800H►DY100:MOVR7,#100;调用
100次为100MS►LOOP:LCALLDY1;调1MS延时子程序►DJNZR7,LOOP;次数未到须循环►RET;次数到则返回主程序返回例4-3-17源程序清单►解:采用指令②01∽E1nnLAJMPaddr散转►程序:MOV
DPTR,#8000H►;数据指针指向拨码开关接口地址►MOVXA,@DPTR;读取拨码开关值►ANLA,#0FH►;屏蔽无用位后得到拨码开关值►RLA;拨码开关值乘2►MOVDPTR,#TAB►;数据指针指向散转表首地址►JMP@A+DPTR►;跳转到散转表后程序转入所指定分支►∶►∶►
ORG1000H;指定散转表首地址►TAB:AJMPTP0;散转表►AJMPTP1►∶►AJMPTP9返回顺序结构模块流程图►Sn均为指令或指令集S1S1S1S1入口出口返回条件结构模块流程图►返回S2S1满足条件?入口出口NY条件结构模块另两种流程图满足条件?满足条件?程序段程序段NYNY
返回循环结构模块流程图►返回循环初态设置循环主体满足循环条件?YN入口出口