收藏 分享(赏)

汇编 语言程序设计.ppt

上传人:myk79025 文档编号:6545278 上传时间:2019-04-16 格式:PPT 页数:74 大小:640KB
下载 相关 举报
汇编 语言程序设计.ppt_第1页
第1页 / 共74页
汇编 语言程序设计.ppt_第2页
第2页 / 共74页
汇编 语言程序设计.ppt_第3页
第3页 / 共74页
汇编 语言程序设计.ppt_第4页
第4页 / 共74页
汇编 语言程序设计.ppt_第5页
第5页 / 共74页
点击查看更多>>
资源描述

1、1,AT89S51汇编语 言程序设计,1,2,2,第4章 目录 4.1 汇编语言程序设计概述4.1.1 单片机编程语言4.1.2 汇编语言语句和格式4.1.3 伪指令 4.2 汇编语言源程序的汇编4.2.1 手工汇编4.2.2 机器汇编,3,4.3 AT89S51汇编语言程序设计举例4.3.1 子程序的设计4.3.2 查表程序设计4.3.3 关键字查找程序设计4.3.4 数据极值查找程序设计4.3.5 数据排序程序设计4.3.6 分支转移程序设计4.3.7 循环程序设计,4,内容概要 汇编语言能直接控制单片机硬件的编程语言。 因此,要求程序设计者要 “软、硬结合” 。 本章介绍汇编语言程序设计

2、的基本知识,以及一些基本的程序设计。4.1 汇编语言程序设计概述 程序是指令的有序集合。 单片机运行就是执行指令序列的过程。 编写这一指令序列的过程称为程序设计。,5,4.1.1 单片机编程语言 常用的编程语言是汇编语言和高级语言。 1汇编语言 用英文字符来代替机器语言,这些英文字符被称为助记符汇编语言:用助记符表示的指令。 汇编语言源程序:用汇编语言编写的程序。 “汇编”:汇编语言源程序需转换(翻译)成为二进制代码表示的机器语言程序,才能识别和执行。 完成“翻译”的程序称为汇编程序。经汇编程序“汇编”得到的以“0”、“1”代码形式表示的机器语言程序称为目标程序。,5,6,优点:用汇编语言编写

3、程序效率高,占用存储空间小,运行速度快,能编写出最优化的程序, 缺点:可读性差,离不开具体的硬件,是面向“硬件”的语言通用性差。 2高级语言 不受具体“硬件”的限制,优点:通用性强,直观、易懂、易学,可读性好。 目前多数的51单片机用户使用C语言(C51)来进行程序设计,已公认为高级语言中高效简洁而又贴近51单片机硬件的编程语言。 将C语言向单片机上移植,始于20世纪80年代的中后期。,6,7,经过十几年努力,C51已成为单片机的实用高级编程语言。 尽管目前已有不少设计人员使用C51来进行程序开发,但在对程序的空间和时间要求较高的场合,汇编语言仍必不可少。 在这种场合下,可使用C语言和汇编语言

4、混合编程。在很多需要直接控制硬件且对实时性要求较高的场合,则更是非用汇编语言不可。 掌握汇编语言并能进行程序设计,是学习和掌握单片机程序设计的基本功之一。 4.1.2 汇编语言语句和格式 两种基本语句:指令语句和伪指令语句。,7,8,(1)指令语句 已在第3章介绍。每一指令语句在汇编时都产生一个指令代码(机器代码),执行该指令代码对应着机器的一种操作。 (2)伪指令语句 是控制汇编(翻译)过程的一些控制命令。在汇编时没有机器代码与之对应。 下面介绍指令语句格式。伪指令语句将在4.1.3节介绍。,9,汇编语言语句是符合典型的汇编语言的四分段格式:标号字段和操作码字段之间要有冒号“:”分隔; 操作

5、码字段和操作数字段间的分界符是空格; 双操作数之间用逗号相隔; 操作数字段和注释字段之间的分界符用分号“;”。 任何语句都必须有操作码字段,其余各段为任选项。,9,10,【例4-1】下面是一段程序的四分段书写格式。 标号字段 操作码字段 操作数字段 注释字段 START:MOV A,#00H ;0AMOV R1,#10 ;10R1MOV R2,#00000011B ;03HR2 LOOP: ADD A,R2 ;(A)+(R2)ADJNZ R1,LOOP ;R1减1不为零,则跳LOOP处NOP HERE:SJMP HERE 上述4个字段应该遵守的基本语法规则如下。,10,11,1标号字段语句所在

6、地址的标志符号,才能被访问。如标号“START”和“LOOP”等。有关标号规定如下: (1)标号后必须跟冒号“:”。 (2)标号由18个ASCII码字符组成,第一个字符必须是字母。 (3)同一标号在一个程序中只能定义一次,不能重复定义。 (4)不能使用汇编语言已经定义的符号作为标号,如指令助记符、伪指令以及寄存器的符号名称等。 (5)标号的有无,取决于本程序中的其他语句是否访,11,12,问该条语句。如无其他语句访问,则该语句前不需标号。 2操作码字段 操作码字段规定了语句执行的操作,操作码是汇编语言指令中唯一不能空缺的部分。 3操作数字段 指令的操作数或操作数地址。 在本字段中,操作数的个数

7、因指令的不同而不同。通常有单操作数、双操作数和无操作数三种情况。 如果是多操作数,则操作数之间要以逗号隔开。,13,操作数表示时,几种情况需注意: (1)十六进制、二进制和十进制形式的操作数表示多数情况,操作数或操作数地址是采用十六进制形式来表示的。则需加后缀“H”。在某些特殊场合用二进制表示,需加后缀“B”若操作数采用十进制形式,则需加后缀“D”,也可省略。 若十六进制操作数以字符AF开头,需在它前面加一个 “0”,以便汇编时把它和字符AF区别开。,13,14,(2)工作寄存器和特殊功能寄存器的表示当操作数为工作寄存器或特殊功能寄存器时,允许用工作寄存器和特殊功能寄存器的代号表示。例如,工作

8、寄存器用R7R0,累加器用A(或Acc)表示。另外,工作寄存器和特殊功能寄存器也可用其地址来表示,如累加器A可用其地址E0H来表示。 4注释字段用于解释指令或程序的含义,对可读性非常有用。使用时须以分号开头,长度不限,一行写不下可换行书写,但注意也要以分号开头。,14,15,汇编时,遇到“;” 就停止“翻译”。因此,注释字段不会产生机器代码。 4.1.3 伪指令在汇编语言源程序中应有向汇编程序发出的指示信息,告诉它如何完成汇编工作,这是通过伪指令来实现。伪指令不属于指令系统中的汇编语言指令,它是程序员发给汇编程序的命令,也称为汇编程序控制命令。只有在汇编前的源程序中才有伪指令。 “伪”体现在汇

9、编后,伪指令没有相应的机器代码产生。伪指令具有控制汇编程序的输入/输出、定义数据和符号、条件汇编、分配存储空间等功能。,15,16,不同汇编语言的伪指令有所不同,但基本内容相同。 介绍常用的伪指令。 1ORG(ORiGin)汇编起始地址命令源程序的开始,用一条ORG伪指令规定程序的起始地址。如果不用ORG,则汇编得到的目标程序将从0000H地址开始。例如:ORG 2000H START: MOV A,#00H 即规定标号START代表地址为2000H开始。 在一源程序中,可多次用ORG指令,规定不同的程序段的起始地址。但是,地址必须由小到大排列,且不能交叉、,17,重叠。例如: ORG 200

10、0H ORG 2500H ORG 3000H 这种顺序是正确的。若按下面顺序的排列则是错误的,因为地址出现了交叉。 ORG 2500H ORG 2000H ORG 3000H ,17,18,2. END(END of Assembly)汇编终止命令 源程序结束标志,终止源程序的汇编工作。整个源程序中只能有一条END命令,且位于程序的最后。如果END出现在程序中间,其后的源程序,将不进行汇编处理。 3EQU(EQUate)标号赋值命令 用于给标号赋值。赋值后,标号值在整个程序有效。 例如:TEST: EQU 2000H 表示TEST=2000H,汇编时,凡是遇到TEST时,均以2000H来代替。

11、,18,19,4DB(Define Byte)定义数据字节命令 用于从指定的地址开始,在程序存储器连续单元中定义字节数据。例如:ORG 2000H DB 30H,40H,24,“C“,“B“ 汇编后 (2000H)=30H (2001H)=40H (2002H)=18H(十进制数24) (2003H)=43H(字符“C”的ASCII码) (2004H)=42H(字符“B”的ASCII码),19,20,显然,DB功能是从指定单元开始定义(存储)若干字节,十进制数自然转换成十六进制数,字母按ASCII码存储。 5DW(Define Word)定义数据字命令 该命令用于从指定的地址开始,在程序存储器

12、的连续单元中定义16位的数据字。例如: ORG 2000H DW 1246H,7BH,10 汇编后 (2000H)=12H ;第1个字 (2001H)=46H (2002H)=00H ;第2个字,21,(2003H)=7BH (2004H)=00H ;第3个字 (2005H)=0AH 6DS(Define Storage)定义存储区命令 从指定地址开始,保留指定数目的字节单元作为存储区,供程序运行使用。例如:TABEL:DS 10 表示从TABEL代表的地址开始,保留10个连续的地址单元。又例如:ORG 2000HDS 10 H 表示从2000H地址开始,保留16个连续地址单元。,21,22,

13、注意:DB、DW和DS命令只能对程序存储器有效,不能对数据存储器使用。 7BIT 位定义命令用于给字符名称赋以位地址,位地址可以是绝对位地址,也可是符号地址。例如:QA BIT P1.6 功能是把P1.6的位地址赋给变量QA。 4.2 汇编语言源程序的汇编 “汇编”?汇编可分为手工汇编和机器汇编两类。,22,23,4.2.1 手工汇编通过查指令的机器代码表(表3-2),逐个把助记符指令“翻译”成机器代码,再进行调试和运行。手工汇编遇到相对转移偏移量的计算时,较麻烦,易出错,只有小程序或受条件限制时才使用。实际中,多采用“汇 编程序”来自动完成汇编。,23,24,4.2.2 机器汇编用微型计算机

14、上的软件(汇编程序)来代替手工汇编。在微机上用编辑软件进行源程序编辑,然后生成一个ASCII码文件,扩展名为 “.ASM”。在微机上运行汇编程序,译成机器码。机器码通过微机的串口(或并口)传送到用户样机(或在线仿真器),进行程序的调试和运行。有时,在分析某些产品的程序的机器代码时,需将机器代码翻译成汇编语言源程序,称为“反汇编”。,24,25,【例4-2】 表4-1是一段源程序的汇编结果,可查表3-2,手工汇编,来验证下面的汇编结果是否正确。机器码从1000H单元开始存放。,25,26,4.3 AT89S51汇编语言程序设计举例介绍常用的汇编语言程序的设计。 4.3.1 子程序的设计将那些需多

15、次应用的、完成相同的某种基本运算或操作的程序段从整个程序中独立出来,单独编成一个程序段,需要时进行调用。这样的程序段称为子程序。优点:采用子程序可使程序结构简单,缩短程序的设计时间,减少占用的程序存储空间。子程序在程序设计中非常重要,读者应熟练掌握子程序的设计方法。,26,27,1子程序的设计原则和应注意的问题 编写子程序应注意以下问题:(1)子程序的入口地址,前必须有标号。(2)主程序调用子程序,是通过调用指令来实现。有两条子程序调用指令: 绝对调用指令ACALL addr11。双字节,addr11指出了调用的目的地址,PC中16位地址中的高5位不变,被调用的子程序的首地址与绝对调用指令的下

16、一条指令的高5位地址相同,即只能在同一个2KB区内。 长调用指令LCALL addr16。三字节,addr16为直接调用的目的地址,子程序可放在64KB程序存储器区任意位置。,27,28,(3)子程序结构中必须用到堆栈,用来进行断点和现场的保护。 (4)子程序返回主程序时,最后一条指令必须是RET指令,功能是把堆栈中的断点地址弹出送入PC指针中,从而实现子程序返回后从主程序断点处继续执行主程序。 (5)子程序可以嵌套,即主程序可以调用子程序,子程序又可以调用另外的子程序。,28,29,2子程序的基本结构 典型的子程序的基本结构如下: MAIN: ;MAIN为主程序入口标号LCALL SUB ;

17、调用子程序SUB 子程序 SUB: PUSH PSW ;现场保护 PUSH Acc POP Acc ;现场恢复,注意要先进后出POP PSW RET ;最后一条指令必须为RET,29,30,注意:上述子程序结构中,现场保护与现场恢复不是必需的,要根据实际情况而定。 4.3.2 查表程序设计查表程序是一种常用程序,避免复杂的运算或转换过程,可完成数据补偿、修正、计算、转换等各种功能,具有程序简单、执行速度快等优点。查表是根据自变量x,在表格寻找y,使y =f(x)。单片机中,数据表格存放于程序存储器内,在执行查表指令时,发出读程序存储器选通脉冲 。两条极为有用的查表指令如下: (1)MOVC A

18、,A+DPTR (2)MOVC A,A+PC,30,31,两条指令的功能完全相同,具体使用有差别。 指令“MOVC A,A+DPTR” 把A中内容与DPTR中的内容相加,结果为某一程序存储单元的地址,然后把该地址单元的内容送到A中。 指令“MOVC A,A+PC” ,PC的内容与A的内容相加后所得的数作为某一程序存储器单元的地址,根据地址取出程序存储器相应单元中的内容送到累加器A,指令执行后,PC的内容不发生变化,仍指向该查表指令的下一条指令。 优点:在于预处理较少且不影响其他特殊功能寄存器的值,不必保护其他特殊功能寄存器。,31,32,缺点:在于该表格只能存放在这条指令的地址X3X2X1X0

19、以下00HFFH之中,即只能存放在地址范围X3X2X1X0+1X3X2X1X0+100H中,这就使得表格所在的程序空间受到了限制。 下面说明查表指令的用法和计算偏移量应注意的问题。,33,【例4-3】 设计一子程序,功能是根据累加器A中的数x(09之间)查x的平方表y,根据x的值查出相应的平方y。本例中的x和y均为单字节数。地 址 子程序 Y3Y2Y1Y0 ADD A,#01H Y3Y2Y1Y0+2 MOVC A,A+PC Y3Y2Y1Y0+3 RET Y3Y2Y1Y0+4 DB 00H,01H,04H,09H,10H DB 19H,24H,31H,40H,51H;数09的平方表,33,34,

20、指令“ADD A,#01H”的作用是A中的内容加上 “01H”, “01H”即为查表指令与平方表之间的“RET”指令所占的字节数。加上 “01H”后,可保证PC指向表首,累加器A中原来的内容仅是从表首开始向下查找多少个单元。 在进入程序前,A的内容在0009H之间,如A中的内容为02H,它的平方为04H,可根据A的内容查出x的平方 指令“MOVC A,A+DPTR” 应用范围较广,使用该指令时不必计算偏移量,优点是表格可以设在64KB程序存储器空间内的任何地方,而不像“MOVC A,A+PC”那样只设在PC下面的256个单元中,所以使用较方便。,34,35,如果DPTR已被使用,则在查表前必须

21、保护DPTR,且结束后恢复DPTR,例4-3可改成如下形式:PUSH DPH ;保存DPHPUSH DPL ;保存DPLMOV DPTR,#TAB1MOVC A,A+DPTRPOP DPL ;恢复DPLPOP DPH ;恢复DPHRET TAB1: DB 00H,01H,04H,09H,10H;平方表DB 19H,24H,31H,40H,51H 实际查表,有时x为单字节数,y为双字节数。来看下例。,35,36,【例4-4】有一巡回检测报警装置,需对16路(x)输入进行检测,每路有一个最大允许值(y),为双字节数。需根据测量的路数(x),查表找出对应该路的最大允许值(y),看输入值是否大于最大允

22、许值,如果大于就报警。 取路数为x(0x15),y为最大允许值,放在表格中。设进入查表程序前,假设路数x已放于R2中,查表后该路的最大允许值y放于R3R4中。查表的程序如下:,36,37,TB3: MOV A,R2ADD A,R2 ;(R2)*2(A)MOV R3,A ;保存指针 ADD A,#6 ;加偏移量MOVC A,A+PC ;查第一字节XCH A,R3ADD A,#3MOVC A,A+PC ;查第二字节MOV R4,ARET TAB3: DW 1520,3721,42645,7580 ;最大值表DW 3483,32657,883,9943DW 10000,40511,6758,8931

23、DW 4468,5871,13284,27808,37,38,表格长度不能超过256B,且表格只能存放于“MOVC A,A+PC”指令以下的256个单元中,如需把表格放在程序存储器空间的任何地方,应使用指令“ MOVC A,A+DPTR”。 【例4-5】 以AT89S51为核心的温度控制器,温度传感器输出的电压与温度为非线性关系,传感器输出的电压已由A/D转换为10位二进制数。测得的不同温度下的电压值数据构成一个表,表中温度值为y(双字节无符号数),x(双字节无符号数)为电压值数据。设测得电压值x放入R2R3中,根据电压值x,查找对应的温度值y,仍放入R2R3中。参考程序:,38,39,LTB

24、2: MOV DPTR,#TAB2MOV A,R3CLR CRLC AMOV R3,AXCH A,R2RLC AXCH R2,AADD A,DPL ;(R2R3)+(DPTR)(DPTR)MOV DPL,AMOV A,DPHADDC A,R2MOV DPH,ACLR A,39,40,MOVC A,A+DPTR ;查第一字节MOV R2,A ;第一字节存入R2中CLR AINC DPTRMOVC A,A+DPTR ;查第二字节MOV R3,A ;第二字节存入R3中RET TAB2: DW , , ;温度值表由于使用了指令“MOVC A,A+DPTR”,表TAB2可放入64KB程序存储器空间任何位

25、置,表格的长度可大于256B。,40,41,4.3.3 关键字查找程序设计 在表中查找关键字的操作,也称为数据检索。有两种方法,即顺序检索和对分检索。 1顺序检索 要检索的表是无序的,检索时只能从第1项开始逐项查找,判断所取数据是否与关键字相等。 【例4-6】 从50个字节的无序表中查找一个关键字“xxH”。 ORG 1000H MOV 30H,#xxH ;关键字xxH送30H单元 MOV R1,#50 ;查找次数送R1 MOV A,#14H ;修正值送A MOV DPTR,#TAB4 ;表首地址送DPTR,41,42,LOOP: PUSH AccMOVC A, A+PC ;查表结果送ACJN

26、E A,30H,LOOP1;(40H)不等于关键字则转LOOP1MOV R2,DPH ;查到关键字,把地址送R2,R3MOV R3,DPL DONE: RET LOOP1:POP Acc ;修正值弹出INC A ;A+1AINC DPTR ;修改数据指针DPTRDJNZ R1,LOOP ;R10,未查完,继续查找MOV R2,#00H ;R1=0,R2和R3清0MOV R3,#00H ;表中50个数已查完AJMP DONE ;从子程序返回TAB4: DB , ;50个无序数据表,42,43,2对分检索 对分检索的前提是检索的数据表已经排好序,以便于按照对分原则取数。如何进行数据排序,稍后介绍。

27、 对分检索的方法:取数据表中间位置的数与关键字进行比较,如相等,则查找结束。 如果取数大于关键字,则下次对分检索的范围是从数据区起点到本次取数处。 如果取数小于关键字,则下次对分检索的范围是从本次取数数据区起点到数据区终点。依此类推,逐渐缩小检索范围,减少次数,大大提高查找速度。,43,44,4.3.4 数据极值查找程序设计 进行数值大小的比较,从一批数据中找出最大值(或最小值)并存于某一单元中。 【例4-7】片内RAM中存放一批数据,查找出最大值并存放于首地址中。设R0中存放首地址,R2中存放字节数,程序框图见图4-1。程序如下:MOV R2,n ;n为要比较的数据字节数MOV A,R0 ;

28、存首地址指针 MOV R1,ADEC R2 MOV A,R1,45,LOOP: MOV R3, ADEC R1CLR CSUBB A,R1 ;两个数比较JNC LOOP1 ;C=0,A中数大,跳LOOP1MOV A,R1 ;C=1,则大数送ASJMP LOOP2 LOOP1:MOV A,R3 LOOP2:DJNZ R2, LOOP ;是否比较结束?MOV R0, A ;存最大数RET,45,46,4.3.5 数据排序程序设计 将一批数由小到大(升序)排列,或由大到小(降序)排列。 最常用的数据排序算法是冒泡法,是相邻数互换的排序方法,因其过程类似水中气泡上浮,故称冒泡法。 排序时,从前向后进行

29、相邻两个数的比较,如果数据的大小次序与要求的顺序不符时,就将两个数互换;否则,顺序符合要求就不互换。如果进行升序排序,应通过这种相邻数互换方法,使小数向前移,大数向后移。 如此从前向后进行一次次相邻数互换(冒泡),就会把这批数据的最大数排到最后,次大数排在倒数第二的位置,,46,47,从而实现一批数据由小到大的排列。假设有7个原始数据的排列顺序为6、4、1、2、5、7、3。第一次冒泡的过程是: 6、4、1、2、5、7、3 ;原始数据的排列 4、6、1、2、5、7、3 ;逆序,互换 4、1、6、2、5、7、3 ;逆序,互换 4、1、2、6、5、7、3 ;逆序,互换 4、1、2、5、6、7、3 ;

30、逆序,互换 4、1、2、5、6、7、3 ;正序,不互换 4、1、2、5、6、3、7 ;逆序,互换,第一次冒泡结束,47,48,如此进行,各次冒泡的结果如下: 第1次冒泡结果:4、1、2、5、6、3、7 第2次冒泡结果:1、2、4、5、3、6、7 第3次冒泡结果:1、2、4、3、5、6、7 第4次冒泡结果:1、2、3、4、5、6、7 ;已完成排序 第5次冒泡结果:1、2、3、4、5、6、7 第6次冒泡结果:1、2、3、4、5、6、7 对于n个数,理论上应进行(n-1)次冒泡才能完成排序,实际上有时不到(n-1)次就已完成排序。,48,49,例如,上面的7个数,应进行6次冒泡,但实际上第4次冒泡时

31、就已经完成排序。 如何判定排序是否已经完成?就是看各次冒泡中是否有互换发生,如果有,则排序还没完成;否则就表示已经排好序。 在程序设计中,常用设置互换标志的方法,用标志的状态表示是否有互换进行。 【例4-8】一批单字节无符号数,以R0为首地址指针,R2中为字节数,将这批数进行升序排列。程序框图如图4-2所示。程序如下:,50,SORT: MOV A,R0 MOV R1,AMOV A,R2 ;字节数送入R5MOV R5,A CLR F0 ;互换标志位F0清0DEC R5 MOV A,R1 LOOP: MOV R3,A INC R1 CLR C MOV A,R1 ;比较大小,50,51,SUBB

32、A,R3 JNC LOOP1 SETB F0 ;互换标志位F0置1MOV A,R3; XCH A,R1 ;两个数互换DEC R1 XCH A,R1 INC R1 LOOP1:MOV A,R1DJNZ R5,LOOPJB F0,SORT RET,51,52,52,图4-2 单字节无符号数排序程序框图,53,4.3.6 分支转移程序设计 分为无条件转移和有条件转移。 无条件分支转移程序很简单,不讨论。有条件分支转移程序按结构类型来分,又分为单分支选择结构和多分支选择结构。 1单分支选择结构 仅有两个出口,两者选一。一般根据运算结果的状态标志,用条件判跳指令来选择并转移。 【例4-9】 求单字节有符

33、号数的二进制补码 正数补码是其本身,负数补码是其反码加1。因此,应首先判被转换数的符号,负数进行转换,正数本身即为补码。,53,54,设二进制数放在A中,其补码放回到A中,框图如图4-3所示。参考程序如下:CMPT: JNB Acc.7,RETURN ;(A)0,不需转换MOV C,Acc.7 ;符号位保存CPL A ;(A)求反,加1ADD A,#1 MOV Acc.7,C ;符号位存在A的最高位 RETURN:RET,54,55,图4-3 求单字节有符号二进制数补码的框图,56,此外,单分支选择结构还有图4-4、图4-5所示的几种形式。,56,图4-4 单分支选择结构2 图4-5 单分支选

34、择结构3,57,2多分支选择结构 当程序的判别部分有两个以上的出口时,为多分支选择结构。有两种形式,如图4-6和图4-7所示。,57,图4-6 多分支选择结构1 图4-7 多分支选择结构2,58,指令系统提供了非常有用的两种多分支选择指令: 间接转移指令 JMP A+DPTR 比较转移指令 CJNE A,direct,relCJNE A,#data,relCJNE Rn,#data,relCJNE Ri,#data,rel 间接转移指令“JMP A+DPTR”由数据指针DPTR决定多分支转移程序的首地址,由A的内容选择对应分支。 4条比较转移指令CJNE能对两个欲比较的单元内容进行比较,当不相

35、等时,程序实现相对转移;若两者相等,则顺序往下执行。,58,59,简单的分支转移程序的设计,常采用逐次比较法,就是把所有不同的情况一个一个地进行比较,发现符合就转向对应的处理程序。缺点是程序太长,有n种可能的情况,就需有n个判断和转移。 【例4-10】 求符号函数的值。符号函数定义如下:X存放在40H单元,Y存放在41H单元,如图4-6所示。,59,60,程序如下: SIGNFUC: MOV A,40HCJNE A,#00H,NZEARAJMP NEGT NZEAR: JB Acc.7, POSIMOV A,#01HAJMP NEGT POSI: MOV A,#81H NEGT: MOV 41

36、H, AEND,60,61,实际中,经常遇到图4-7的分支转移程序设计,典型例子就是当单片机系统中的键盘按下时,就会得到一个键值,根据不同的键值,跳向不同的键处理程序入口。此时,可用直接转移指令(LJMP或AJMP指令)组成一个转移表,然后把该单元的内容读入累加器A,转移表首地址放入DPTR中,再利用间接转移指令实现分支转移。 【例4-11】 根据寄存器R2的内容,转向各个处理程序PRGX(X=0n)。(R2)=0,转PRG0(R2)=1,转PRG1(R2)=n,转PRGn,61,62,程序如下: JMP6: MOV DPTR,#TAB5 ;转移表首地址送DPTRMOV A,R2 ;分支转移参

37、量送AMOV B,#03H ;乘数3送BMUL AB ;分支转移参量乘3MOV R6, A ;乘积的低8位暂存R6MOV A,B ;乘积的高8位送AADD A ,DPH ;乘积的高8位加到DPH中MOV DPH, A MOV A, R6JMP A+DPTR ;多分支转移选择,62,63,TAB5: LJMP PRG0 ;多分支转移表LJMP PRG1LJMP PRGn R2中的分支转移参量乘3是由于长跳转指令LJMP要占3个单元。本例程序可位于64KB程序存储器空间的任何区域。 4.3.7 循环程序设计 程序中含有可以反复执行的程序段,称循环体。例如,求100个数的累加和,没必要连续安排100

38、条加法指令,用一条加法指令使其循环执行100次。因此可缩短程序长度和程序所占的内存单元数量更少,使程序结构紧凑。,63,64,1循环程序的结构 主要由以下四部分组成。 (1)循环初始化 完成循环前的准备工作。例如,循环控制计数初值的设置、地址指针的起始地址的设置、为变量预置初值等。 (2)循环处理 完成实际的处理工作,反复循环执行的部分,故又称循环体。 (3)循环控制 在重复执行循环体的过程中,不断修改循环控制变量,直到符合结束条件,就结束循环程序的执行。,64,65,循环结束控制方法分为循环计数控制法和条件控制法。 (4)循环结束 这部分是对循环程序执行的结果进行分析、处理和存放。 2循环结

39、构的控制 分为循环计数控制结构和条件控制结构。 图4-8是计数循环控制结构,图4-9是条件控制结构。,65,66,66,图4-8 计数循环控制结构 图4-9 条件控制结构,67,(1)计数循环控制结构 依据计数器的值来决定循环次数,一般为减1计数器,计数器减到“0”时,结束循环。计数器初值在初始化设定。 MCS51指令系统提供了功能极强的循环控制指令: DJNZ Rn,rel ;以工作寄存器作控制计数器 DJNZ direct,rel ;以直接寻址单元作控制计数器例如,计算n个数据的和,计算公式为 。 如直接按公式编写程序,则n=100时,需编写连续的100次加法。这样程序将太长,并且n可变时

40、,将无法编写出程序。,67,68,公式要改写为用程序实现的形式,用下式表示程序框图见图4-10。,68,图4-10 求数据和的程序框图,69,【例4-12】 求n个单字节无符号数xi的和,xi按i顺序存放在AT89S51单片机内部RAM从50H开始的单元中,n放在R2中,和(双字节)放在R3R4中。 程序如下: ADD1: MOV R2,#n ;加法次数n送R2 MOV R3,#0 ;R3存放和的高8位,初始值为0MOV R4,#0 ;R4存放和的低8位,初始值为0MOV R0,#50H LOOP: MOV A,R4ADD A,R0MOV R4,AINC R0CLR A,69,70,ADDC

41、A,R3MOV R3,ADJNZ R2,LOOP ;判加法循环次数是否已到?END 用寄存器R2作为计数控制变量,R0作为变址单元,用它来寻址xi。 一般来说,循环工作部分中的数据应该用间接方式来寻址,如这里用:ADD A,R0 计数控制只有在循环次数已知的情况下才适用。循环次数未知,不能用循环次数来控制,往往需要根据某种条件来判断是否应该终止循环。,70,71,(2)条件控制结构 结构见图4-9。循环控制中,设置一个条件,判是否满足该条件,如满足,则循环结束。如不满足该条件则循环继续。 【例4-13】 一串字符,依次存放在内部RAM从30H单元开始的连续单元中,字符串以0AH为结束标志,测试

42、字符串长度。 采用逐个字符依次与“0AH”比较(设置的条件)的方法。设置一个累计字符串长度的长度计数器和一个用于指定字符串指针。 如果字符与“0AH”不等,则长度计数器和字符串指针都加1;如果比较相等,则表示该字符为“0AH”,字符串结束,计数器值就是字符串的长度。程序如下:,71,72,MOV R4,#0FFH ;长度计数器初值送R4MOV R1,#2FH ;字符串指针初值送R1 NEXT: INC R4INC R1CJNE R1,#0AH,NEXT;比较,不等则进行下一;字符比较END 上面两例都是在一个循环程序中不再包含其他循环程序,则称该循环程序为单循环程序。如果一个循环程序中包含了其

43、他循环程序,则称为多重循环程序。 最常见的多重循环是由DJNZ指令构成的软件延时程序,是常用程序之一。,72,73,【例4-14】 50ms延时程序。 软件延时程序与指令执行时间有很大的关系。在使用12MHz晶振时,一个机器周期为1s,执行一条DJNZ指令的时间为2s。可用双重循环方法的延时50ms程序:DEL: MOV R7,#200 ;本指令执行时间1sDEL1:MOV R6,#125 ;本指令执行时间1sDEL2:DJNZ R6,DEL2 ;指令执行1次为2s,计 ; 1252 s=250sDJNZ R7,DEL1 ;指令执行时间2s,本循环体 ; 执行125次RET ;指令执行时间2s,73,74,以上延时程序不是太精确,如把所有指令的执行时间计算在内,它的延时时间为 1+(1+250+2) 200+2s=50.603ms, 如要求比较精确的延时,应对上述程序进行修改,才能达到较为精确的延时时间。但要注意,用软件实现延时程序,不允许有中断,否则将严重影响定时的准确性。 对于延时更长的时间,可采用多重的循环,如1s延时,可用三重循环。,74,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 网络科技 > C/C++资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报