1、第第4 4章章 AT89S51AT89S51汇编语言汇编语言程序设计程序设计1成都理工大学工程技术学院成都理工大学工程技术学院自动化工程系自动化工程系2 第第4章章 目录目录4.1 汇编语言程序设计概述汇编语言程序设计概述 4.1.1 单片机编程语言 4.1.2 汇编语言语句和格式 4.1.3 伪指令4.2 汇编语言源程序的汇编汇编语言源程序的汇编 4.2.1 手工汇编 4.2.2 机器汇编4.3 AT89S51汇编语言程序设计举例汇编语言程序设计举例 4.3.1 子程序的设计 4.3.2 查表程序设计 4.3.3 关键字查找程序设计 4.3.4 数据极值查找程序设计 4.3.5 数据排序程序
2、设计 4.3.6 分支转移程序设计 4.3.7 循环程序设计内容概要内容概要汇编语言能汇编语言能直接控制单片机硬件直接控制单片机硬件的的编程语言编程语言。因此,要求程序设计者要因此,要求程序设计者要 “软、硬结合软、硬结合”。本章介绍汇编语言程序设计的本章介绍汇编语言程序设计的基本知识基本知识,以及一些以及一些基本的基本的程序设计程序设计。4.1 汇编语言程序设计概述汇编语言程序设计概述程序是指令的有序集合。程序是指令的有序集合。单片机运行就是执行指令序列的过程。单片机运行就是执行指令序列的过程。编写这一指令序列的过程称为编写这一指令序列的过程称为程序设计。程序设计。4.1.1 4.1.1 单
3、片机编程语言单片机编程语言常用的编程语言是常用的编程语言是汇编语言汇编语言和和高级语言高级语言。1 1汇编语言汇编语言用英文字符来代替机器语言,这些英文字符被称为用英文字符来代替机器语言,这些英文字符被称为助记助记符汇编语言:符汇编语言:用助记符表示的指令。用助记符表示的指令。汇编语言源程序:汇编语言源程序:用汇编语言编写的程序。用汇编语言编写的程序。“汇编汇编”:汇编语言源程序需汇编语言源程序需转换(翻译)转换(翻译)成为二进制成为二进制代码表示的机器语言程序,才能识别和执行。代码表示的机器语言程序,才能识别和执行。完成完成“翻译翻译”的程序称为的程序称为汇编程序汇编程序。经汇编程序。经汇编
4、程序“汇编汇编”得到的以得到的以“0 0”、“1 1”代码形式表示的机器语言程序称代码形式表示的机器语言程序称为为目标程序目标程序。5优点:优点:用汇编语言编写程序效率高,占用存储空间小,运行用汇编语言编写程序效率高,占用存储空间小,运行速度快,能编写出最优化的程序,速度快,能编写出最优化的程序,缺点:缺点:可读性差,离不开具体的硬件,是面向可读性差,离不开具体的硬件,是面向“硬件硬件”的语的语言通用性差。言通用性差。2 2高级语言高级语言不受具体不受具体“硬件硬件”的限制,的限制,优点:优点:通用性强,直观、易懂、通用性强,直观、易懂、易学,可读性好。易学,可读性好。目前多数的目前多数的51
5、单片机用户单片机用户使用使用C语言(语言(C51)来进行程序设计来进行程序设计,已公认为高级语言中高效简洁而又贴近,已公认为高级语言中高效简洁而又贴近51单片机硬件的编程单片机硬件的编程语言。语言。将将C语言向单片机上移植,始于语言向单片机上移植,始于20世纪世纪80年代的中后期。年代的中后期。6经过十几年努力,经过十几年努力,C51C51已成为单片机的实用高级编程语言。已成为单片机的实用高级编程语言。尽管目前已有不少设计人员使用尽管目前已有不少设计人员使用C51C51来进行程序开发,但在来进行程序开发,但在对对程序的程序的空间空间和和时间时间要求较高的场合,汇编语言仍必不可少。要求较高的场合
6、,汇编语言仍必不可少。在这种场合下,可使用在这种场合下,可使用C C语言和汇编语言混合编程。在很多语言和汇编语言混合编程。在很多需要直接控制硬件且对实时性要求较高的场合,则更是非用汇需要直接控制硬件且对实时性要求较高的场合,则更是非用汇编语言不可。编语言不可。掌握汇编语言并能进行程序设计,是学习和掌握单片机程序掌握汇编语言并能进行程序设计,是学习和掌握单片机程序设计的设计的基本功之一基本功之一。4.1.2 4.1.2 汇编语言语句和格式汇编语言语句和格式两种基本语句:两种基本语句:指令语句指令语句和和伪指令语句伪指令语句。7(1 1)指令语句)指令语句已在第已在第3 3章介绍。每一指令语句在汇
7、编时都产生一个指令代码章介绍。每一指令语句在汇编时都产生一个指令代码(机器代码),执行该指令代码对应着机器的一种操作。(机器代码),执行该指令代码对应着机器的一种操作。(2 2)伪指令语句)伪指令语句是控制汇编(翻译)过程的一些是控制汇编(翻译)过程的一些控制命令控制命令。在汇编时。在汇编时没有机没有机器代码器代码与之对应。与之对应。下面介绍指令语句格式。伪指令语句将在下面介绍指令语句格式。伪指令语句将在4.1.34.1.3节介绍。节介绍。汇编语言语句是符合典型的汇编语言的汇编语言语句是符合典型的汇编语言的四分段四分段格式格式:标号字段标号字段和和操作码字段操作码字段之间要有之间要有冒号冒号“
8、:”分隔;分隔;操作码字段操作码字段和和操作数字段间操作数字段间的分界符是的分界符是空格空格;双操作数双操作数之间用之间用逗号逗号相隔;相隔;操作数字段操作数字段和和注释字段注释字段之间的分界符用之间的分界符用分号分号“;”。任何语句都必须有操作码字段任何语句都必须有操作码字段,其余各段为任选项。,其余各段为任选项。9标号字段标号字段(LABLE)操作码字段操作码字段(OPCODE)操作数字段操作数字段(OPRAND)注释字段注释字段(COMMENT)【例例4-1】下面是一段程序的下面是一段程序的四分段四分段书写格式。书写格式。标号字段标号字段 操作码字段操作码字段 操作数字段操作数字段 注释
9、字段注释字段START:MOVA,#00H ;0A MOVR1,#10 ;10R1MOVR2,#00000011B ;03HR2LOOP:ADDA,R2 ;(A)+(R2)ADJNZR1,LOOP ;R1减减1不为零,则跳不为零,则跳LOOP处处NOPHERE:SJMPHERE上述上述4个字段应该遵守的个字段应该遵守的基本语法规则基本语法规则如下。如下。101 1标号字段标号字段语句所在地址的标志符号,才能被访问。如标号语句所在地址的标志符号,才能被访问。如标号“STARTSTART”和和“LOOPLOOP”等。有关标号规定如下:等。有关标号规定如下:(1 1)标号后必须跟冒号标号后必须跟冒号
10、“:”。(2 2)标号由标号由1 18 8个个ASCIIASCII码字符组成,第一个字符必须是码字符组成,第一个字符必须是字母。字母。(3 3)同一标号在一个程序中只能定义一次,不能重复定同一标号在一个程序中只能定义一次,不能重复定义。义。(4 4)不能使用汇编语言已经定义的符号作为标号,如指不能使用汇编语言已经定义的符号作为标号,如指令助记符、伪指令以及寄存器的符号名称等。令助记符、伪指令以及寄存器的符号名称等。(5 5)标号的有无,取决于本程序中的其他语句是否访标号的有无,取决于本程序中的其他语句是否访11问该条语句。如无其他语句访问,则该语句前不需标号。问该条语句。如无其他语句访问,则该
11、语句前不需标号。2 2操作码字段操作码字段操作码字段规定了语句执行的操作,操作码是汇编语言指令中操作码字段规定了语句执行的操作,操作码是汇编语言指令中唯一不能空缺的部分。唯一不能空缺的部分。3 3操作数字段操作数字段指令的操作数或操作数地址。指令的操作数或操作数地址。在本字段中,在本字段中,操作数的个数因指令的不同而不同。操作数的个数因指令的不同而不同。通常有单操通常有单操作数、双操作数和无操作数三种情况。作数、双操作数和无操作数三种情况。如果是多操作数,则操作数之间要以如果是多操作数,则操作数之间要以逗号逗号隔开。隔开。操作数表示操作数表示时,几种情况需注意:时,几种情况需注意:(1 1)十
12、六进制、二进制和十进制形式的操作数表示)十六进制、二进制和十进制形式的操作数表示多数情况,操作数或操作数地址是采用多数情况,操作数或操作数地址是采用十六进制十六进制形式来表形式来表示的。则需加示的。则需加后缀后缀“H H”。在某些特殊场合用在某些特殊场合用二进制二进制表示,需加表示,需加后缀后缀“B B”若操作数采用若操作数采用十进制十进制形式,则需加形式,则需加后缀后缀“D D”,也可省略。,也可省略。若十六进制若十六进制操作数操作数以以字符字符A AF F开头开头,需在它,需在它前面加一个前面加一个“0 0”,以便汇编时把它和,以便汇编时把它和字符字符A AF F区别区别开。开。13(2
13、2)工作寄存器和特殊功能寄存器的表示)工作寄存器和特殊功能寄存器的表示 当操作数为工作寄存器或特殊功能寄存器时,允许用当操作数为工作寄存器或特殊功能寄存器时,允许用工作寄存器和特殊功能寄存器的工作寄存器和特殊功能寄存器的代号表示代号表示。例如,例如,工作寄存器用工作寄存器用R7R7R0R0,累加器用,累加器用A A(或(或AccAcc)表)表示。另外,工作寄存器和特殊功能寄存器也可用其地址来示。另外,工作寄存器和特殊功能寄存器也可用其地址来表示,如累加器表示,如累加器A A可用其地址可用其地址E0HE0H来表示。来表示。4 4注释字段注释字段用于解释指令或程序的含义,对可读性非常有用。用于解释
14、指令或程序的含义,对可读性非常有用。使用时使用时须以分号开头须以分号开头,长度不限,一行写不下,长度不限,一行写不下可换行可换行书写,但注意也要以分号开头。书写,但注意也要以分号开头。14 汇编时,遇到汇编时,遇到“;”就停止就停止“翻译翻译”。因此,注释字。因此,注释字段不会产生机器代码。段不会产生机器代码。4.1.3 4.1.3 伪指令伪指令 在汇编语言源程序中应有在汇编语言源程序中应有向汇编程序发出的指示信息向汇编程序发出的指示信息,告诉它如何完成汇编工作,这是通过告诉它如何完成汇编工作,这是通过伪指令伪指令来实现。来实现。伪指令不属于指令系统中的汇编语言指令,它伪指令不属于指令系统中的
15、汇编语言指令,它是程序员是程序员发给汇编程序的发给汇编程序的命令命令,也称为,也称为汇编程序控制命令汇编程序控制命令。只有在汇编前的源程序中才有伪指令。只有在汇编前的源程序中才有伪指令。“伪伪”体现在体现在汇编后,伪指令汇编后,伪指令没有相应的机器代码产生。没有相应的机器代码产生。伪指令具有控制汇编程序的输入伪指令具有控制汇编程序的输入/输出、定义数据和符输出、定义数据和符号、条件汇编、分配存储空间等功能。号、条件汇编、分配存储空间等功能。15不同汇编语言的伪指令有所不同,但基本内容相同。不同汇编语言的伪指令有所不同,但基本内容相同。介绍介绍常用的伪指令常用的伪指令。1ORG(ORiGin)汇
16、编起始地址命令)汇编起始地址命令源程序的开始,用一条源程序的开始,用一条ORG伪指令规定伪指令规定程序的起始地程序的起始地址址。如果不用如果不用ORG,则汇编得到的目标程序,则汇编得到的目标程序将从将从0000H地地址开始。例如:址开始。例如:ORG2000HSTART:MOVA,#00H 即规定标号即规定标号START代表地址为代表地址为2000H开始。开始。在一源程序中,可多次用在一源程序中,可多次用ORG指令,规定不同的程序段的指令,规定不同的程序段的起始地址。但是,起始地址。但是,地址必须由小到大排列,且不能交叉、地址必须由小到大排列,且不能交叉、重叠。例如:重叠。例如:ORG2000
17、HORG2500HORG3000H这种顺序是正确的。若按下面顺序的排列则是错误的,因为地址出现了交叉。ORG2500HORG2000HORG3000H172.2.END(END of Assembly)END(END of Assembly)汇编终止命令汇编终止命令源程序源程序结束标志结束标志,终止源程序的汇编工作。终止源程序的汇编工作。整个源程序整个源程序中只能有一条中只能有一条ENDEND命令,且命令,且位于程序的最后位于程序的最后。如果。如果ENDEND出现出现在程序中间,其后的源程序,将不进行汇编处理。在程序中间,其后的源程序,将不进行汇编处理。3 3EQUEQU(EQUateEQUa
18、te)标号赋值命令)标号赋值命令用于用于给标号赋值给标号赋值。赋值后,标号值在整个程序有效。赋值后,标号值在整个程序有效。例如:例如:TESTTEST:EQU 2000HEQU 2000H表示表示TEST=2000HTEST=2000H,汇编时,凡是遇到,汇编时,凡是遇到TESTTEST时,均以时,均以2000H2000H来代替。来代替。184DB(Define Byte)定义数据字节命令)定义数据字节命令用于从指定的地址开始,在程序存储器连续单元中定义用于从指定的地址开始,在程序存储器连续单元中定义字节数据。例如:字节数据。例如:ORG 2000HDB30H,40H,24,C,B汇编后汇编后
19、(2000H)=30H(2001H)=40H(2002H)=18H(十进制数十进制数24)(2003H)=43H(字符字符“C”的的ASCII码码)(2004H)=42H(字符字符“B”的的ASCII码码)19显然,显然,DB功能是从指定单元开始定义(存储)若干字节,功能是从指定单元开始定义(存储)若干字节,十进制数自然转换成十六进制数,字母按十进制数自然转换成十六进制数,字母按ASCII码存储。码存储。5DW(Define Word)定义数据字命令)定义数据字命令该命令用于从指定的地址开始,在程序存储器的连续单元中该命令用于从指定的地址开始,在程序存储器的连续单元中定义定义16位的数据字。例
20、如:位的数据字。例如:ORG2000HDW1246H,7BH,10汇编后(2000H)=12H;第1个字(2001H)=46H(2002H)=00H;第2个字(2003H)=7BH(2004H)=00H;第;第3个字个字(2005H)=0AH6DS(Define Storage)定义存储区命令)定义存储区命令从指定地址开始,保留指定数目的字节单元作为存储区,从指定地址开始,保留指定数目的字节单元作为存储区,供程序运行使用。供程序运行使用。例如:例如:TABEL:DS10表示从表示从TABEL代表的地址开始,保留代表的地址开始,保留10个连续的地址单个连续的地址单元。元。又例如又例如:ORG20
21、00HDS10 H表示从表示从2000H地址开始,保留地址开始,保留16个连续地址单元。个连续地址单元。21注意:注意:DBDB、DWDW和和DSDS命令命令只能对程序存储器有效,只能对程序存储器有效,不能对不能对数据存储器数据存储器使用。使用。7 7BIT BIT 位定义命令位定义命令用于给字符名称赋以位地址,位地址可以是绝对位地用于给字符名称赋以位地址,位地址可以是绝对位地址,也可是符号地址。例如:址,也可是符号地址。例如:QAQABIT P1.6BIT P1.6功能是把功能是把P1.6P1.6的位地址赋给变量的位地址赋给变量QAQA。4.2 4.2 汇编语言源程序的汇编汇编语言源程序的汇
22、编“汇编汇编”-可分为可分为手工汇编手工汇编和和机器汇编机器汇编两类。两类。224.2.1 4.2.1 手工汇编手工汇编 通过查指令的通过查指令的机器代码表(表机器代码表(表3-23-2),),逐个把助记符指令逐个把助记符指令“翻译翻译”成机器代码,再进行调试和运行。成机器代码,再进行调试和运行。手工汇编手工汇编遇到相对转移偏移量的计算时,较麻烦,易出遇到相对转移偏移量的计算时,较麻烦,易出错,只有小程序或受条件限制时才使用。实际中,多采用错,只有小程序或受条件限制时才使用。实际中,多采用“汇汇编程序编程序”来自动完成汇编。来自动完成汇编。234.2.2 4.2.2 机器汇编机器汇编 用微型计
23、算机上的用微型计算机上的软件软件(汇编程序汇编程序)来代替手工汇编。在微来代替手工汇编。在微机上用编辑软件进行源程序编辑,然后生成一个机上用编辑软件进行源程序编辑,然后生成一个ASCIIASCII码文件,码文件,扩展名为扩展名为“.ASM.ASM”。在微机上运行汇编程序,译成机器码。在微机上运行汇编程序,译成机器码。机器码通过微机的串口(或并口)传送到用户样机(或在机器码通过微机的串口(或并口)传送到用户样机(或在线仿真器),进行程序的调试和运行。线仿真器),进行程序的调试和运行。有时,在分析某些产品的程序的机器代码时,有时,在分析某些产品的程序的机器代码时,需将需将机器代机器代码码翻译成翻译
24、成汇编语言源程序汇编语言源程序,称为,称为“反汇编反汇编”。24【例例4-2】表4-1是一段源程序的汇编结果,可查表3-2,手工汇编,来验证下面的汇编结果是否正确。机器码从1000H单元开始存放。254.3 AT89S514.3 AT89S51汇编语言程序设计举例汇编语言程序设计举例 介绍常用的汇编语言程序的设计。介绍常用的汇编语言程序的设计。4.3.1 4.3.1 子程序的设计子程序的设计 将那些需多次应用的、完成相同的某种基本运算或操作将那些需多次应用的、完成相同的某种基本运算或操作的程序段从整个程序中独立出来,单独编成一个程序段,的程序段从整个程序中独立出来,单独编成一个程序段,需要时进
25、行调用。这样的程序段称为需要时进行调用。这样的程序段称为子程序子程序。优点:优点:采用子程序可使程序结构简单,缩短程序的设计采用子程序可使程序结构简单,缩短程序的设计时间,减少占用的程序存储空间。时间,减少占用的程序存储空间。子程序在程序设计中非常重要,读者应熟练掌握子程序子程序在程序设计中非常重要,读者应熟练掌握子程序的设计方法。的设计方法。261 1子程序的设计原则和应注意的问题子程序的设计原则和应注意的问题编写子程序应注意以下问题:编写子程序应注意以下问题:(1 1)子程序的入口地址,前必须有标号。)子程序的入口地址,前必须有标号。(2 2)主程序调用子程序,是通过调用指令来实现。有)主
26、程序调用子程序,是通过调用指令来实现。有两两条子程序调用指令条子程序调用指令:绝对调用指令绝对调用指令ACALL addr11ACALL addr11。双字节,。双字节,addr11addr11指出了指出了调用的目的地址,调用的目的地址,PCPC中中1616位地址中的高位地址中的高5 5位不变,被调用的位不变,被调用的子程序的首地址与绝对调用指令的下一条指令的高子程序的首地址与绝对调用指令的下一条指令的高5 5位地址位地址相同,即只能在同一个相同,即只能在同一个2KB2KB区内。区内。长调用指令长调用指令LCALL addr16LCALL addr16。三字节,三字节,addr16addr16
27、为直接调为直接调用的目的地址,子程序可放在用的目的地址,子程序可放在64KB64KB程序存储器区任意位置。程序存储器区任意位置。27(3 3)子程序结构中必须用到)子程序结构中必须用到堆栈堆栈,用来进行断点和现场的,用来进行断点和现场的保护。保护。(4 4)子程序返回主程序时,)子程序返回主程序时,最后一条指令必须是最后一条指令必须是RETRET指令指令,功能是把功能是把堆栈中的断点地址堆栈中的断点地址弹出送入弹出送入PCPC指针中,从而实现子程指针中,从而实现子程序返回后从主程序断点处继续执行主程序。序返回后从主程序断点处继续执行主程序。(5 5)子程序可以)子程序可以嵌套嵌套,即主程序可以
28、调用子程序,子程序,即主程序可以调用子程序,子程序又可以调用另外的子程序。又可以调用另外的子程序。282子程序的基本结构子程序的基本结构典型的子程序的基本结构如下:MAIN:;MAIN为主程序入口标号LCALL SUB;调用子程序SUB 子程序SUB:PUSH PSW;现场保护 PUSH AccPOP Acc;现场恢复,注意要先进后出POP PSW RET;最后一条指令必须为RET29子程序处理程序段子程序子程序 注意:注意:上述子程序结构中,现场保护与现场恢复不是必需上述子程序结构中,现场保护与现场恢复不是必需的,要根据实际情况而定。的,要根据实际情况而定。4.3.2 4.3.2 查表程序设
29、计查表程序设计 查表程序是一种常用程序查表程序是一种常用程序,避免避免复杂的运算或转换过程,复杂的运算或转换过程,可完成数据补偿、修正、计算、转换等各种功能,具有程序可完成数据补偿、修正、计算、转换等各种功能,具有程序简单、执行速度快等简单、执行速度快等优点优点。查表查表是根据是根据自变量自变量x x,在表格,在表格寻找寻找y y,使,使y y=f f(x x)。单片机。单片机中,数据表格存放于中,数据表格存放于程序存储器程序存储器内,在执行查表指令时,发内,在执行查表指令时,发出读程序存储器选通脉冲出读程序存储器选通脉冲 。两条两条极为有用的查表指令如下:极为有用的查表指令如下:(1 1)M
30、OVC MOVC A A,A+DPTRA+DPTR(2 2)MOVC MOVC A A,A+PCA+PC30两条指令的功能完全相同,具体使用有差别。两条指令的功能完全相同,具体使用有差别。指令指令“MOVC AMOVC A,A+DPTRA+DPTR”把把A A中内容与中内容与DPTRDPTR中的内容相加中的内容相加,结果为某一程序存储单元的地址,然后把该地址单元的内容,结果为某一程序存储单元的地址,然后把该地址单元的内容送到送到A A中。中。指令指令“MOVC AMOVC A,A+PCA+PC”,PCPC的内容与的内容与A A的内容相加后所得的内容相加后所得的数作为某一程序存储器单元的地址,根
31、据地址取出程序存储的数作为某一程序存储器单元的地址,根据地址取出程序存储器相应单元中的内容送到累加器器相应单元中的内容送到累加器A A,指令执行后,指令执行后,PCPC的内容不发的内容不发生变化,仍指向该查表指令的下一条指令。生变化,仍指向该查表指令的下一条指令。优点:优点:在于预处理较少且不影响其他特殊功能寄存器的值,在于预处理较少且不影响其他特殊功能寄存器的值,不必保护其他特殊功能寄存器。不必保护其他特殊功能寄存器。31缺点:缺点:在于该表格只能存放在这条指令的地址在于该表格只能存放在这条指令的地址X3X2X1X0X3X2X1X0以下以下00H00HFFHFFH之中,即只能存放在地址范围之
32、中,即只能存放在地址范围X3X2X1X0+1X3X2X1X0+1X3X2X1X0+100HX3X2X1X0+100H中,这就使得表格所在的程序空间受到了中,这就使得表格所在的程序空间受到了限制。限制。下面说明下面说明查表指令的用法查表指令的用法和和计算偏移量计算偏移量应注意的问题。应注意的问题。【例例4-3】设计一子程序,功能是根据累加器A中的数x(09之间)查x的平方表y,根据x的值查出相应的平方y。本例中的x和y均为单字节数。地地 址址 子程序子程序Y3Y2Y1Y0ADD A,#01HY3Y2Y1Y0+2MOVC A,A+PCY3Y2Y1Y0+3RETY3Y2Y1Y0+4DB 00H,01
33、H,04H,09H,10HDB 19H,24H,31H,40H,51H;数09的平方表33指令指令“ADD AADD A,#01H#01H”的作用的作用是是A A中的内容加上中的内容加上 “01H01H”,“01H01H”即为查表指令与平方表之间的即为查表指令与平方表之间的“RETRET”指令所占的字节数。加上指令所占的字节数。加上“01H01H”后,可保证后,可保证PCPC指向表首指向表首,累加器,累加器A A中原来的内容仅是从表首开始向下查找多少个中原来的内容仅是从表首开始向下查找多少个单元。单元。在进入程序前,在进入程序前,A A的内容在的内容在000009H09H之间,如之间,如A A
34、中的内容中的内容为为02H02H,它的平方为,它的平方为04H04H,可根据,可根据A A的内容查出的内容查出x x的平方的平方指令指令“MOVC AMOVC A,A+DPTRA+DPTR”应用范围较广,使用该指应用范围较广,使用该指令时不必计算偏移量,优点是表格可以设在令时不必计算偏移量,优点是表格可以设在64KB64KB程序存储程序存储器空间内的任何地方,而不像器空间内的任何地方,而不像“MOVC AMOVC A,A+PCA+PC”那样只那样只设在设在PCPC下面的下面的256256个单元中,所以使用较方便。个单元中,所以使用较方便。34如果DPTR已被使用,则在查表前必须保护DPTR,且
35、结束后恢复DPTR,例4-3可改成如下形式:PUSH DPH ;保存DPH PUSH DPL ;保存DPL MOV DPTR,#TAB1MOVC A,A+DPTRPOP DPL ;恢复DPLPOP DPH ;恢复DPHRETTAB1:DB 00H,01H,04H,09H,10H;平方表 DB 19H,24H,31H,40H,51H实际查表,有时x为单字节数,y为双字节数。来看下例。35【例例4-4】有一巡回检测报警装置,需对16路(x)输入进行检测,每路有一个最大允许值(y),为双字节数。需根据测量的路数(x),查表找出对应该路的最大允许值(y),看输入值是否大于最大允许值,如果大于就报警。取
36、路数为x(0 x15),y为最大允许值,放在表格中。设进入查表程序前,假设路数x已放于R2中,查表后该路的最大允许值y放于R3R4中。查表的程序如下:36 TB3:MOV A,R2ADDA,R2 ;(R2)*2(A)MOV R3,A ;保存指针 ADDA,#6 ;加偏移量MOVC A,A+PC ;查第一字节XCH A,R3 ADD A,#3 MOVC A,A+PC ;查第二字节 MOVR4,ARETTAB3:DW 1520,3721,42645,7580;最大值表 DW 3483,32657,883,9943DW 10000,40511,6758,8931DW 4468,5871,13284,
37、2780837表格长度不能超过表格长度不能超过256B256B,且表格只能存放于,且表格只能存放于“MOVC AMOVC A,A+PCA+PC”指令以下的指令以下的256256个单元中,如需把表格放在程序存储个单元中,如需把表格放在程序存储器空间的任何地方,应使用指令器空间的任何地方,应使用指令“MOVC AMOVC A,A+DPTRA+DPTR”。【例例4-54-5】以以AT89S51AT89S51为核心的温度控制器,温度传感器为核心的温度控制器,温度传感器输出的电压与温度为非线性关系,传感器输出的电压已由输出的电压与温度为非线性关系,传感器输出的电压已由A/DA/D转换为转换为1010位二
38、进制数。测得的不同温度下的电压值数据位二进制数。测得的不同温度下的电压值数据构成一个表,表中温度值为构成一个表,表中温度值为y y(双字节无符号数),(双字节无符号数),x x(双字(双字节无符号数)为电压值数据。设测得电压值节无符号数)为电压值数据。设测得电压值x x放入放入R2R3R2R3中,中,根据根据电压值电压值x x,查找对应的,查找对应的温度值温度值y y,仍放入,仍放入R2R3R2R3中。参考程中。参考程序:序:38 LTB2:MOVDPTR,#TAB2MOVA,R3CLRC RLCA MOVR3,A XCHA,R2 RLCA XCHR2,A ADDA,DPL ;(R2R3)+(
39、DPTR)(DPTR)MOVDPL,A MOVA,DPH ADDC A,R2 MOVDPH,A CLRA39MOVC A,A+DPTR;查第一字节MOVR2,A ;第一字节存入R2中CLRAINCDPTRMOVC A,A+DPTR ;查第二字节MOVR3,A ;第二字节存入R3中RETTAB2:DW,;温度值表由于使用了指令“MOVC A,A+DPTR”,表TAB2可放入64KB程序存储器空间任何位置,表格的长度可大于256B。404.3.3 关键字查找程序设计关键字查找程序设计在表中查找关键字的操作,也称为数据检索。有两种方法,即顺序检索和对分检索。1顺序检索顺序检索要检索的表是无序无序的,
40、检索时只能从第只能从第1项开始逐项查项开始逐项查找找,判断所取数据是否与关键字相等。【例例4-6】从50个字节的无序表中查找一个关键字“xxH”。ORG1000HMOV30H,#xxH;关键字xxH送30H单元MOVR1,#50;查找次数送R1MOVA,#14H;修正值送AMOV DPTR,#TAB4;表首地址送DPTR41LOOP:PUSH AccMOVC A,A+PC;查表结果送A CJNE A,30H,LOOP1;(30H)不等于关键字则转LOOP1 MOV R2,DPH;查到关键字,把地址送R2,R3MOV R3,DPLDONE:RETLOOP1:POP Acc;修正值弹出INC A;
41、A+1AINC DPTR;修改数据指针DPTRDJNZ R1,LOOP;R10,未查完,继续查找MOVR2,#00H;R1=0,R2和R3清0MOVR3,#00H;表中50个数已查完AJMPDONE;从子程序返回 TAB4:DB,;50个无序数据表422对分检索对分检索对分检索的前提是检索的数据表已经排好序已经排好序,以便于按照对分原则取数。如何进行数据排序,稍后介绍。对分检索的方法对分检索的方法:取数据表中间位置的数与关键字进行比较,如相等,则查找结束。如果取数大于关键字取数大于关键字,则下次对分检索的范围是从数据区起点到本次取数处。如果取数小于关键字取数小于关键字,则下次对分检索的范围是从
42、本次取数数据区起点到数据区终点。依此类推,逐渐缩小检索范围,减少次数,大大提高查找速度。434.3.4 数据极值查找程序设计数据极值查找程序设计进行数值大小的比较,从一批数据中找出最大最大值(或最小值最小值)并存于某一单元中。【例例4-7】片内RAM中存放一批数据,查找出最大值并存放于首地址中。设R0中存放首地址,R2中存放字节数,程序框图见图4-1。程序如下:MOV R2,n;n为要比较的数据字节数MOV A,R0;存首地址指针MOV R1,ADEC R2MOV A,R1LOOP:MOV R3,ADEC R1CLR CSUBB A,R1;两个数比较JNC LOOP1;C=0,A中数大,跳LO
43、OP1MOV A,R1;C=1,则大数送ASJMP LOOP2LOOP1:MOV A,R3 LOOP2:DJNZ R2,LOOP;是否比较结束?MOV R0,A;存最大数 RET454.3.5 数据排序程序设计数据排序程序设计将一批数由小到大(升序升序)排列,或由大到小(降序降序)排列。最常用的数据排序算法是冒泡法冒泡法,是相邻数互换的排序方法,因其过程类似水中气泡上浮,故称冒泡法。排序时,从前向后进行相邻两个数的比较从前向后进行相邻两个数的比较,如果数据的大数据的大小次序小次序与要求的顺序不符时要求的顺序不符时,就将两个数互换两个数互换;否则,顺序符合要求就不互换。如果进行升序排序,应通过这
44、种相邻数互换方法,使小数向前移,大数向后移。如此从前向后进行一次次相邻数互换(冒泡),(冒泡),就会把这批数据的最大数排到最后,次大数排在倒数第二的位置,46从而实现一批数据由小到大的排列。假设有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 ;逆序,互换4、1、2、5、6、7、3 ;正序,不互换4、1、2、5、6、3、7 ;逆序,互换,第一次冒泡结束47如此进行,各次冒泡的结果如
45、下:如此进行,各次冒泡的结果如下:第第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例如,上面的例如,上面的7个数个
46、数,应进行,应进行6次次冒泡冒泡,但,但实际上实际上第第4次次冒泡时冒泡时就已经完成就已经完成排序。排序。如何判定排序是否已经完成如何判定排序是否已经完成?就是看各次冒泡中?就是看各次冒泡中是否有是否有互换互换发发生生,如果有,则排序,如果有,则排序还没完成还没完成;否则就表示已经排好序。;否则就表示已经排好序。在程序设计中,常用在程序设计中,常用设置互换标志设置互换标志的方法,用标志的状态表示的方法,用标志的状态表示是否有互换进行。是否有互换进行。【例例4-8】一批单字节无符号数,以一批单字节无符号数,以R0为首地址指针,为首地址指针,R2中为中为字节数,将这批数进行升序排列。程序框图如字节
47、数,将这批数进行升序排列。程序框图如图图4-2所示。程所示。程序如下:序如下:SORT:MOV A,R0 MOV R1,AMOV A,R2;字节数送入R5MOV R5,ACLR F0;互换标志位F0清0DEC R5MOV A,R1 LOOP:MOV R3,AINC R1CLR CMOV A,R1;比较大小50SUBB A,R3JNC LOOP1SETB F0;互换标志位F0置1MOV A,R3;XCH A,R1;两个数互换DEC R1XCH A,R1INC R1LOOP1:MOV A,R1DJNZ R5,LOOPJB F0,SORT RET5152图图4-24-2 单字节无符号数排序程序框图4
48、.3.6 分支转移程序设计分支转移程序设计分为无条件转移分为无条件转移和和有条件转移有条件转移。无条件分支转移程序很简单,不讨论。有条件分支转移程序无条件分支转移程序很简单,不讨论。有条件分支转移程序按结构类型来分,又分为按结构类型来分,又分为单分支单分支选择结构选择结构和和多分支多分支选择结构选择结构。1单分支选择结构单分支选择结构 仅有仅有两个出口两个出口,两者选一两者选一。一般根据运算结果的状态标志,。一般根据运算结果的状态标志,用用条件判跳指令条件判跳指令来选择并转移。来选择并转移。【例例4-9】求单字节有符号数的二进制补码求单字节有符号数的二进制补码正数补码正数补码是其本身,是其本身
49、,负数补码负数补码是其是其反码加反码加1。因此,应首先。因此,应首先判被转换数的符号,负数进行转换,正数本身即为补码。判被转换数的符号,负数进行转换,正数本身即为补码。53设二进制数放在A中,其补码放回到A中,框图如图图4-3所所示示。参考程序如下:CMPT:JNB Acc.7,RETURN;(A)0,不需转换 MOV C,Acc.7;符号位保存 CPL A;(A)求反,加1 ADD A,#1 MOV Acc.7,C;符号位存在A的最高位RETURN:RET54图图4-34-3 求单字节有符号二进制数补码的框图求单字节有符号二进制数补码的框图此外,单分支选择结构还有图图4-4、图图4-5所示的
50、几种形式。56图4-4 单分支选择结构2 图4-5 单分支选择结构32多分支选择结构多分支选择结构当程序的判别部分有两个以上两个以上的出口出口时,为多分支选择结构。有两种形式,如图4-6和图图4-7所示。57 图图4-64-6 多分支选择结构1 1 图图4-74-7 多分支选择结构2指令系统提供了非常有用的指令系统提供了非常有用的两种多分支选择指令两种多分支选择指令:间接转移指令间接转移指令 JMP A+DPTR比较转移指令比较转移指令 CJNE A,direct,rel CJNE A,#data,rel CJNE Rn,#data,rel CJNE Ri,#data,rel间接转移指令间接转