资源描述
*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,第,4,章,AT89S51,汇编语 言程序设计,1,4.3 AT89S51,汇编语言程序设计举例,4.3.1,子程序的设计,4.3.2,查表程序设计,4.3.3,关键字查找程序设计,4.3.4,数据极值查找程序设计,4.3.5,数据排序程序设计,4.3.6,分支转移程序设计,4.3.7,循环程序设计,3,内容概要,汇编语言能,直接控制单片机硬件,的,编程语言,。,因此,要求程序设计者要,“软、硬结合”,。,本章介绍汇编语言程序设计的,基本知识,以及一些,基本的程序设计,。,4.1,汇编语言程序设计概述,程序是指令的有序集合。,单片机运行就是执行指令序列的过程。,编写这一指令序列的过程称为,程序设计。,4,4.1.1,单片机编程语言,常用的编程语言是,汇编语言,和,高级语言,。,1,汇编语言,用英文字符来代替机器语言,这些英文字符被称为,助记符汇编语言:,用助记符表示的指令。,汇编语言源程序:,用汇编语言编写的程序。,“汇编”:,汇编语言源程序需,转换(翻译),成为二进制代码表示的机器语言程序,才能识别和执行。,完成“翻译”的程序称为,汇编程序,。经汇编程序“汇编”得到的以“,0,”、“,1,”代码形式表示的机器语言程序称为,目标程序,。,5,优点:,用汇编语言编写程序效率高,占用存储空间小,运行速度快,能编写出最优化的程序,,缺点:,可读性差,离不开具体的硬件,是面向“硬件”的语言通用性差。,2,高级语言,不受具体“硬件”的限制,,优点:,通用性强,直观、易懂、易学,可读性好。,目前多数的,51,单片机用户,使用,C,语言(,C51,),来进行程序设计,已公认为高级语言中高效简洁而又贴近,51,单片机硬件的编程语言。,将,C,语言向单片机上移植,始于,20,世纪,80,年代的中后期。,6,(,1,)指令语句,已在第,3,章介绍。每一指令语句在汇编时都产生一个指令代码(机器代码),执行该指令代码对应着机器的一种操作。,(,2,)伪指令语句,是控制汇编(翻译)过程的一些,控制命令,。在汇编时,没有机器代码,与之对应。,下面介绍指令语句格式。伪指令语句将在节介绍。,8,汇编语言语句是符合典型的汇编语言的,四分段,格式,:,标号字段,和,操作码字段,之间要有,冒号“:”,分隔;,操作码字段,和,操作数字段间,的分界符是,空格,;,双操作数,之间用,逗号,相隔;,操作数字段,和,注释字段,之间的分界符用,分号“;”,。,任何语句都必须有操作码字段,,其余各段为任选项。,9,标号字段,(LABLE),操作码字段,(OPCODE),操作数字段,(OPRAND),注释字段,(COMMENT),【,例,4-1,】,下面是一段程序的,四分段,书写格式。,标号字段 操作码字段 操作数字段 注释字段,START,:,MOVA,,,#00H,;,0,A,MOVR1,,,#10,;,10,R1,MOVR2,,,#00000011B,;,03H,R2,LOOP,:,ADDA,,,R2,;,(A)+(R2),A,DJNZR1,,,LOOP,;,R1,减,1,不为零,则跳,LOOP,处,NOP,HERE,:,SJMPHERE,上述,4,个字段应该遵守的,基本语法规则,如下。,10,问该条语句。如无其他语句访问,则该语句前不需标号。,2,操作码字段,操作码字段规定了语句执行的操作,操作码是汇编语言指令中唯一不能空缺的部分。,3,操作数字段,指令的操作数或操作数地址。,在本字段中,,操作数的个数因指令的不同而不同。,通常有单操作数、双操作数和无操作数三种情况。,如果是多操作数,则操作数之间要以,逗号,隔开。,12,操作数表示,时,几种情况需注意:,(,1,)十六进制、二进制和十进制形式的操作数表示,多数情况,操作数或操作数地址是采用,十六进制,形式来表示的。则需加,后缀“,H,”。,在某些特殊场合用,二进制,表示,需加,后缀“,B,”,若操作数采用,十进制,形式,则需加,后缀“,D,”,,也可省略。,若十六进制,操作数,以,字符,A,F,开头,,需在它,前面加一个“,0,”,,以便汇编时把它和,字符,A,F,区别,开。,13,(,2,)工作寄存器和特殊功能寄存器的表示,当操作数为工作寄存器或特殊功能寄存器时,允许用工作寄存器和特殊功能寄存器的,代号表示,。,例如,,工作寄存器用,R7,R0,,累加器用,A,(或,Acc,)表示。另外,工作寄存器和特殊功能寄存器也可用其地址来表示,如累加器,A,可用其地址,E0H,来表示。,4,注释字段,用于解释指令或程序的含义,对可读性非常有用。,使用时,须以分号开头,,长度不限,一行写不下,可换行,书写,但注意也要以分号开头。,14,汇编时,遇到“;”就停止“翻译”。因此,注释字段不会产生机器代码。,4.1.3,伪指令,在汇编语言源程序中应有,向汇编程序发出的指示信息,,告诉它如何完成汇编工作,这是通过,伪指令,来实现。,伪指令不属于指令系统中的汇编语言指令,它,是程序员发给汇编程序的,命令,,也称为,汇编程序控制命令,。,只有在汇编前的源程序中才有伪指令。,“伪”体现在,汇编后,伪指令,没有相应的机器代码产生。,伪指令具有控制汇编程序的输入,/,输出、定义数据和符号、条件汇编、分配存储空间等功能。,15,不同汇编语言的伪指令有所不同,但基本内容相同。,介绍,常用的伪指令,。,1,ORG,(,ORiGin,)汇编起始地址命令,源程序的开始,用一条,ORG,伪指令规定,程序的起始地址,。,如果不用,ORG,,则汇编得到的目标程序,将从,0000H,地址开始。例如:,ORG2000H,START,:,MOVA,,,#00H,即规定标号,START,代表地址为,2000H,开始。,在一源程序中,可多次用,ORG,指令,规定不同的程序段的起始地址。但是,,地址必须由小到大排列,且不能交叉、,重叠。例如:,ORG2000H,ORG2500H,ORG3000H,这种顺序是正确的。若按下面顺序的排列则是错误的,因为地址出现了交叉。,ORG2500H,ORG2000H,ORG3000H,17,2.END(END of Assembly),汇编终止命令,源程序,结束标志,,,终止源程序的汇编工作。,整个源程序中只能有一条,END,命令,且,位于程序的最后,。如果,END,出现在程序中间,其后的源程序,将不进行汇编处理。,3,EQU,(,EQUate,)标号赋值命令,用于,给标号赋值,。赋值后,标号值在整个程序有效。,例如:,TEST,:,EQU 2000H,表示,TEST=2000H,,汇编时,凡是遇到,TEST,时,均以,2000H,来代替。,18,4,DB,(,Define Byte,)定义数据字节命令,用于从指定的地址开始,在程序存储器连续单元中定义字节数据。例如:,ORG2000H,DB30H,,,40H,,,24,,,C,,,B,汇编后,(2000H)=30H,(2001H)=40H,(2002H)=18H(,十进制数,24),(2003H)=43H(,字符“,C,”的,ASCII,码,),(2004H)=42H(,字符“,B,”的,ASCII,码,),19,显然,,DB,功能是从指定单元开始定义(存储)若干字节,十进制数自然转换成十六进制数,字母按,ASCII,码存储。,5,DW,(,Define Word,)定义数据字命令,该命令用于从指定的地址开始,在程序存储器的连续单元中定义,16,位的数据字。例如:,ORG2000H,DW1246H,,,7BH,,,10,汇编后,(2000H)=12H,;第,1,个字,(2001H)=46H,(2002H)=00H,;第,2,个字,20,(2003H)=7BH,(2004H)=00H,;第,3,个字,(2005H)=0AH,6,DS,(,Define Storage,)定义存储区命令,从指定地址开始,保留指定数目的字节单元作为存储区,供程序运行使用。,例如:,TABEL,:,DS10,表示从,TABEL,代表的地址开始,保留,10,个连续的地址单元。,又例如,:,ORG2000H,DS10 H,表示从,2000H,地址开始,保留,16,个连续地址单元。,21,注意:,DB,、,DW,和,DS,命令,只能对程序存储器有效,,不能对数据存储器,使用。,7,BIT,位定义命令,用于给字符名称赋以位地址,位地址可以是绝对位地址,也可是符号地址。例如:,功能是把的位地址赋给变量,QA,。,4.2,汇编语言源程序的汇编,“汇编”,-,可分为,手工汇编,和,机器汇编,两类。,22,4.2.1,手工汇编,通过查指令的,机器代码表(表,3-2,),,逐个把助记符指令“翻译”成机器代码,再进行调试和运行。,手工汇编,遇到相对转移偏移量的计算时,较麻烦,易出错,只有小程序或受条件限制时才使用。实际中,多采用“汇,编程序”来自动完成汇编。,23,4.2.2,机器汇编,用微型计算机上的,软件,(,汇编程序,),来代替手工汇编。在微机上用编辑软件进行源程序编辑,然后生成一个,ASCII,码文件,扩展名为“,.ASM,”。在微机上运行汇编程序,译成机器码。,机器码通过微机的串口(或并口)传送到用户样机(或在线仿真器),进行程序的调试和运行。,有时,在分析某些产品的程序的机器代码时,,需将,机器代码,翻译成,汇编语言源程序,,称为,“反汇编”。,24,【,例,4-2,】,表,4-1,是一段源程序的汇编结果,可查,表,3-2,,手工汇编,来验证下面的汇编结果是否正确。机器码从,1000H,单元开始存放。,25,4.3 AT89S51,汇编语言程序设计举例,介绍常用的汇编语言程序的设计。,4.3.1,子程序的设计,将那些需多次应用的、完成相同的某种基本运算或操作的程序段从整个程序中独立出来,单独编成一个程序段,需要时进行调用。这样的程序段称为,子程序,。,优点:,采用子程序可使程序结构简单,缩短程序的设计时间,减少占用的程序存储空间。,子程序在程序设计中非常重要,读者应熟练掌握子程序的设计方法。,26,1,子程序的设计原则和应注意的问题,编写子程序应注意以下问题:,(,1,)子程序的入口地址,前必须有标号。,(,2,)主程序调用子程序,是通过调用指令来实现。有,两条子程序调用指令,:,绝对调用指令,ACALL addr11,。双字节,,addr11,指出了调用的目的地址,,PC,中,16,位地址中的高,5,位不变,被调用的子程序的首地址与绝对调用指令的下一条指令的高,5,位地址相同,即只能在同一个,2KB,区内。,长调用指令,LCALL addr16,。,三字节,,addr16,为直接调用的目的地址,子程序可放在,64KB,程序存储器区任意位置。,27,(,3,)子程序结构中必须用到,堆栈,,用来进行断点和现场的保护。,(,4,)子程序返回主程序时,,最后一条指令必须是,RET,指令,,功能是把,堆栈中的断点地址,弹出送入,PC,指针中,从而实现子程序返回后从主程序断点处继续执行主程序。,(,5,)子程序可以,嵌套,,即主程序可以调用子程序,子程序又可以调用另外的子程序。,28,2,子程序的基本结构,典型的子程序的基本结构如下:,MAIN,:,;,MAIN,为主程序入口标号,LCALL SUB,;调用子程序,SUB,子程序,SUB,:,PUSH PSW,;现场保护,PUSH Acc,POP Acc,;现场恢复,注意要先进后出,POP PSW,RET,;最后一条指令必须为,RET,29,子程序处理程序段,子程序,注意:,上述子程序结构中,现场保护与现场恢复不是必需的,要根据实际情况而定。,4.3.2,查表程序设计,查表程序是一种常用程序,避免,复杂的运算或转换过程,可完成数据补偿、修正、计算、转换等各种功能,具有程序简单、执行速度快等,优点,。,查表,是根据,自变量,x,,在表格,寻找,y,,使,y,=,f,(,x,),。单片机中,数据表格存放于,程序存储器,内,在执行查表指令时,发出读程序存储器选通脉冲,。,两条,极为有用的查表指令如下:,(,1,),MOVC A,,,A+DPTR,(,2,),MOVC A,,,A+PC,30,两条指令的功能完全相同,具体使用有差别。,指令“,MOVC A,,,A+DPTR,”,把,A,中内容与,DPTR,中的内容相加,结果为某一程序存储单元的地址,然后把该地址单元的内容送到,A,中。,指令“,MOVC A,,,A+PC,”,,,PC,的内容与,A,的内容相加后所得的数作为某一程序存储器单元的地址,根据地址取出程序存储器相应单元中的内容送到累加器,A,,指令执行后,,PC,的内容不发生变化,仍指向该查表指令的下一条指令。,优点:,在于预处理较少且不影响其他特殊功能寄存器的值,不必保护其他特殊功能寄存器。,31,缺点:,在于该表格只能存放在这条指令的地址,X3X2X1X0,以下,00H,FFH,之中,即只能存放在地址范围,X3X2X1X0+1,X3X2X1X0+100H,中,这就使得表格所在的程序空间受到了限制。,下面说明,查表指令的用法,和,计算偏移量,应注意的问题。,32,【,例,4-3,】,设计一子程序,功能是根据累加器,A,中的数,x,(,0,9,之间)查,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,,,10HDB 19H,,,24H,,,31H,,,40H,,,51H,;数,0,9,的平方表,33,指令“,ADD A,,,#01H,”的作用,是,A,中的内容加上“,01H,”,“,01H,”即为查表指令与平方表之间的“,RET,”指令所占的字节数。加上“,01H,”后,可保证,PC,指向表首,累加器,A,中原来的内容仅是从表首开始向下查找多少个单元。,在进入程序前,,A,的内容在,00,09H,之间,如,A,中的内容为,02H,,它的平方为,04H,,可根据,A,的内容查出,x,的平方,指令,“,MOVC A,,,A+DPTR,”,应用范围较广,使用该指令时不必计算偏移量,优点是表格可以设在,64KB,程序存储器空间内的任何地方,而不像“,MOVC A,,,A+PC,”那样只设在,PC,下面的,256,个单元中,所以使用较方便。,34,如果,DPTR,已被使用,则在查表前必须保护,DPTR,,且结束后恢复,DPTR,,,例,4-3,可改成如下形式:,PUSH DPH,;保存,DPH,PUSH DPL,;保存,DPL,MOV DPTR,,,#TAB1,MOVC A,,,A+DPTR,POP DPL,;恢复,DPL,POP DPH,;恢复,DPH,RET,TAB1,:,DB 00H,,,01H,,,04H,,,09H,,,10H,;平方表,DB 19H,,,24H,,,31H,,,40H,,,51H,实际查表,有时,x,为单字节数,,,y,为双字节数,。来看下例。,35,【,例,4-4,】,有一巡回检测报警装置,需对,16,路(,x,),输入进行检测,每路有一个,最大允许值(,y,),,为,双字节数,。,需根据测量的路数(,x,),查表找出对应该路的最大允许值(,y,),,看输入值是否大于最大允许值,如果大于就报警。,取路数为,x,(,0,x,15,),,y,为最大允许值,放在表格中。设进入查表程序前,假设路数,x,已放于,R2,中,查表后该路的最大允许值,y,放于,R3R4,中。查表的程序如下:,36,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,;最大值表,DW 3483,,,32657,,,883,,,9943,DW 10000,,,40511,,,6758,,,8931,DW 4468,,,5871,,,13284,,,27808,37,表格长度不能超过,256B,,且表格只能存放于“,MOVC A,,,A+PC,”指令以下的,256,个单元中,如需把表格放在程序存储器空间的任何地方,应使用指令“,MOVC A,,,A+DPTR,”。,【,例,4-5】,以,AT89S51,为核心的温度控制器,温度传感器输出的电压与温度为非线性关系,传感器输出的电压已由,A/D,转换为,10,位二进制数。测得的不同温度下的电压值数据构成一个表,表中温度值为,y,(双字节无符号数),,x,(双字节无符号数)为电压值数据。设测得电压值,x,放入,R2R3,中,根据,电压值,x,,查找对应的,温度值,y,,仍放入,R2R3,中。参考程序:,38,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,39,MOVC A,,,A+DPTR,;查第一字节,MOVR2,,,A,;第一字节存入,R2,中,CLRA,INCDPTR,MOVC A,,,A+DPTR,;查第二字节,MOVR3,,,A,;第二字节存入,R3,中,RET,TAB2,:,DW,,,,,;温度值表,由于使用了指令“,MOVC A,,,A+DPTR,”,表,TAB2,可放入,64KB,程序存储器空间任何位置,表格的长度可大于,256B,。,40,4.3.3,关键字查找程序设计,在表中查找关键字的操作,也称为,数据检索,。有两种方法,即,顺序检索,和,对分检索,。,1,顺序检索,要检索的表是,无序,的,检索时,只能从第,1,项开始逐项查找,,判断所取数据是否与关键字相等。,【,例,4-6,】,从,50,个字节的无序表中查找一个关键字“,xxH,”。,ORG1000H,MOV30H,,,#xxH,;关键字,xxH,送,30H,单元,MOVR1,,,#50,;查找次数送,R1,MOVA,,,#14H,;修正值送,A,MOV DPTR,,,#TAB4,;表首地址送,DPTR,41,LOOP,:,PUSH Acc,MOVC A,,,A+PC,;查表结果送,A,CJNE A,,,30H,,,LOOP1,;,(30H),不等于关键字则转,LOOP1,MOV R2,,,DPH,;查到关键字,把地址送,R2,,,R3,MOV R3,,,DPL,DONE,:,RET,LOOP1,:,POP Acc,;修正值弹出,INC A,;,A+1,A,INC DPTR,;修改数据指针,DPTR,DJNZ R1,,,LOOP,;,R1,0,,未查完,继续查找,MOVR2,,,#00H,;,R1=0,,,R2,和,R3,清,0,MOVR3,,,#00H,;表中,50,个数已查完,AJMPDONE,;从子程序返回,TAB4,:,DB,,,,,;,50,个无序数据表,42,2,对分检索,对分检索的前提是检索的数据表,已经排好序,,以便于按照对分原则取数。如何进行数据排序,稍后介绍。,对分检索的方法,:,取数据表中间位置的数与关键字进行比较,如相等,则查找结束。,如果,取数大于关键字,,则下次对分检索的范围是从数据区起点到本次取数处。,如果,取数小于关键字,,则下次对分检索的范围是从本次取数数据区起点到数据区终点。依此类推,逐渐缩小检索范围,减少次数,大大提高查找速度。,43,4.3.4,数据极值查找程序设计,进行数值大小的比较,从一批数据中找出,最大,值,(或,最小值,)并存于某一单元中。,【,例,4-7,】,片内,RAM,中存放一批数据,查找出最大值并存放于首地址中。设,R0,中存放首地址,,R2,中存放字节数,程序框图见图,4-1,。程序如下:,MOV R2,,,n,;,n,为要比较的数据字节数,MOV A,,,R0,;存首地址指针,MOV R1,,,A,DEC R2,MOV A,,,R1,44,LOOP,:,MOV R3,,,A,DEC R1,CLR C,SUBB A,,,R1,;两个数比较,JNC LOOP1,;,C=0,,,A,中数大,跳,LOOP1,MOV A,,,R1,;,C=1,,则大数送,A,SJMP LOOP2,LOOP1,:,MOV A,,,R3,LOOP2,:,DJNZ R2,,,LOOP,;是否比较结束?,MOV R0,,,A,;存最大数,RET,45,4.3.5,数据排序程序设计,将一批数由小到大(,升序,)排列,或由大到小(,降序,)排列。,最常用的数据排序算法是,冒泡法,,是相邻数互换的排序方法,因其过程类似水中气泡上浮,故称冒泡法。,排序时,,从前向后进行相邻两个数的比较,,如果,数据的大小次序,与,要求的顺序不符时,,就将,两个数互换,;否则,顺序符合要求就不互换。如果进行,升序排序,,应通过这种相邻数互换方法,使,小数向前移,,,大数向后移,。,如此从前向后进行一次次,相邻数互换,(冒泡),,就会把这批数据的最大数排到最后,次大数排在倒数第二的位置,,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,如此进行,各次冒泡的结果如下:,第,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,个数,,应进行,6,次,冒泡,,但,实际上,第,4,次,冒泡时就已经完成,排序。,如何判定排序是否已经完成,?就是看各次冒泡中,是否有,互换,发生,,如果有,则排序,还没完成,;否则就表示已经排好序。,在程序设计中,常用,设置互换标志,的方法,用标志的状态表示是否有互换进行。,【,例,4-8,】,一批单字节无符号数,以,R0,为首地址指针,,R2,中为字节数,将这批数进行升序排列。程序框图如,图,4-2,所示。程序如下:,49,SORT,:,MOV A,,,R0,MOV R1,,,A,MOV A,,,R2,;字节数送入,R5,MOV R5,,,A,CLR F0,;互换标志位,F0,清,0,DEC R5,MOV A,,,R1,LOOP,:,MOV R3,,,A,INC R1,CLR C,MOV A,,,R1,;比较大小,50,SUBB A,,,R3,JNC LOOP1,SETB F0,;互换标志位,F0,置,1,MOV A,,,R3,;,XCH A,,,R1,;两个数互换,DEC R1,XCH A,,,R1,INC R1,LOOP1,:,MOV A,,,R1,DJNZ R5,,,LOOP,JB F0,,,SORT,RET,51,52,图,4-2,单字节无符号数排序程序框图,4.3.6,分支转移程序设计,分为无条件转移,和,有条件转移,。,无条件分支转移程序很简单,不讨论。有条件分支转移程序按结构类型来分,又分为,单分支,选择结构,和,多分支,选择结构,。,1,单分支选择结构,仅有,两个出口,,,两者选一,。一般根据运算结果的状态标志,用,条件判跳指令,来选择并转移。,【,例,4-9,】,求单字节有符号数的二进制补码,正数补码,是其本身,,负数补码,是其,反码加,1,。因此,应首先判被转换数的符号,负数进行转换,正数本身即为补码。,53,设二进制数放在,A,中,其补码放回到,A,中,框图如,图,4-3,所示,。参考程序如下:,CMPT,:,,RETURN,;,(A)0,,不需转换,MOV C,,,Acc.7,;符号位保存,CPL A,;,(A),求反,加,1,ADD A,,,#1,,,C,;符号位存在,A,的最高位,RETURN,:,RET,54,在表中查找关键字的操作,也称为数据检索。,用英文字符来代替机器语言,这些英文字符被称为助记符汇编语言:用助记符表示的指令。,TABEL:DS10,MOVR1,#50;,DEL:MOV R7,#200;,LCALL SUB;,CPL A;,1+(1+250+2)200+2s,,程序中含有可以反复执行的程序段,称循环体。,不受具体“硬件”的限制,优点:通用性强,直观、易懂、易学,可读性好。,在汇编语言源程序中应有向汇编程序发出的指示信息,告诉它如何完成汇编工作,这是通过伪指令来实现。,(1)十六进制、二进制和十进制形式的操作数表示,LOOP:ADDA,R2 ;,SJMP LOOP2,NZEAR:,POSI,图,4-3,求单字节有符号二进制数补码的框图,55,此外,单分支选择结构还有,图,4-4,、,图,4-5,所示的几种形式。,56,图,4-4,单分支选择结构,2,图,4-5,单分支选择结构,3,2,多分支选择结构,当程序的判别部分有,两个以上,的,出口,时,为多分支选择结构。有两种形式,如,图,4-6,和,图,4-7,所示。,57,图,4-6,多分支选择结构,1,图,4-7,多分支选择结构,2,指令系统提供了非常有用的,两种多分支选择指令,:,间接转移指令,JMP A+DPTR,比较转移指令,CJNE A,,,direct,,,rel,CJNE A,,,#data,,,rel,CJNE R,n,,,#data,,,rel,CJNE R,i,,,#data,,,rel,间接转移指令“,JMP A+DPTR,”由数据指针,DPTR,决定多,分支转移,程序的,首地址,,由,A,的内容选择对应分支。,4,条,比较转移指令,CJNE,能对两个欲比较的单元内容进行比较,当,不相等,时,程序实现相对转移;若,两者相等,,则顺序往下执行。,58,简单的分支转移程序的设计,常采用,逐次比较法,,就是把所有不同的情况一个一个地进行比较,发现符合就转向对应的处理程序。,缺点,是程序太长,有,n,种可能的情况,就需有,n,个判断和转移。,【,例,4-10,】,求符号函数的值。符号函数定义如下:,X,存放在,40H,单元,,Y,存放在,41H,单元,如,图,4-6,所示。,59,Y,=,1,X,0,X,0,X,=0,0,-,1,程序如下:,SIGNFUC,:,MOV A,,,40H,CJNE A,,,#00H,,,NZEAR,AJMP NEGT,NZEAR,:,,POSI,MOV A,,,#01H,AJMPNEGT,POSI,:,MOVA,,,#81H,NEGT,:,MOV41H,,,A,END,60,实际中,经常遇到,图,4-7,的分支转移程序设计,,典型例子,就是当单片机系统中的,键盘按下,时,就会得到一个键值,根据,不同的键值,,,跳向不同的键处理程序入口,。此时,可,用直接转移指令(,LJMP,或,AJMP,指令)组成一个转移表,,然后把该单元的内容读入累加器,A,,转移表首地址放入,DPTR,中,再利用间接转移指令实现分支转移。,【,例,4-11,】,根据寄存器,R2,的内容,转向各个处理程序,PRG,X,(,X,=0,n,)。,(R2)=0,,转,PRG0,(R2)=1,,转,PRG1,(R2)=,n,,转,PRG,n,61,程序如下:,JMP6,:,MOVDPTR,,,#TAB5,;转移表首地址送,DPTR,MOV A,,,R2,;分支转移参量送,A,MOV B,,,#03H,;乘数,3,送,B,MUL AB,;分支转移参量乘,3,MOV R6,,,A,;乘积的低,8,位暂存,R6,MOV A,,,B,;乘积的高,8,位送,A,ADD A,,,DPH,;乘积的高,8,位加到,DPH,中,MOV DPH,,,A,MOV A,,,R6,JMP A+DPTR,;多分支转移选择,62,TAB5,:,LJMP PRG0,;多分支转移表,LJMP PRG1,LJMP PRG,n,R2,中的,分支转移参量乘,3,是由于长跳转指令,LJMP,要占,3,个单元。本例程序可位于,64KB,程序存储器空间的任何区域。,4.3.7,循环程序设计,程序中含有可以,反复执行,的,程序段,,称,循环体,。,例如,求,100,个数的累加和,,没必要连续安排,100,条加法指令,用,一条加法指令,使其循环执行,100,次。因此可,缩短程序长度,和程序所,占的内存单元数量更少,,使,程序结构紧凑,。,63,1,循环程序的结构,主要由以下四部分组成。,(,1,)循环初始化,完成循环前的,准备工作,。,例如,,循环控制计数初值的设置、地址指针的起始地址的设置、为变量预置初值等。,(,2,)循环处理,完成实际的处理工作,反复循环执行的部分,故又称循环体。,(,3,)循环控制,在重复执行循环体的过程中,不断修改循环控制变量,直到符合结束条件,就结束循环程序的执行。,64,循环结束控制方法分为,循环计数控制法,和,条件控制法,。,(,4,)循环结束,这部分是对循环程序执行的结果进行分析、处理和存放。,2,循环结构的控制,分为,循环计数控制结构,和,条件控制结构,。,图,4-8,是计数循环控制结构,,图,4-9,是条件控制结构。,65,66,图,4-8,计数循环控制结构,图,4-9,条件控制结构,(,1,)计数循环控制结构,依据,计数器的值,来决定循环次数,一般为,减,1,计数器,,计数器减到“,0,”时,结束循环。计数器初值在初始化设定。,MCS51,指令系统提供了功能极强的循环控制指令:,DJNZ R,n,,,rel,;以工作寄存器作控制计数器,DJNZ direct,,,rel,;以直接寻址单元作控制,计数器,例如,,计算,n,个数据的和,计算公式为 。,如直接按公式编写程序,则,n,=100,时,需编写连续的,100,次加法。这样程序将太长,并且,n,可变时,将无法编写出程序。,67,公式要改写为用程序实现的形式,用下式表示,程序框图见,图,4-10,。,68,图,4-10,求数据和的程序框图,【,例,4-12,】,求,n,个单字节无符号数,x,i,的和,,x,i,按,i,顺序存放在,AT89S51,单片机内部,RAM,从,50H,开始的单元中,,n,放在,R2,中,和(双字节)放在,R3R4,中。,程序如下:,ADD1,:,MOVR2,,,#n,;加法次数,n,送,R2,MOV R3,,,#0,;,R3,存放和的高,8,位,初始值为,0,MOV R4,,,#0,;,R4,存放和的低,8,位,初始值为,0,MOV R0,,,#50H,LOOP,:,MOV A,,,R4,ADD A,,,R0,MOV R4,,,A,INC R0,CLR A,69,ADDC A,,,R3,MOV R3,,,A,DJNZ R2,,,LOOP,;判加法循环次数是否已到?,END,用寄存器,R2,作为计数控制变量,,R0,作为变址单元,用它来寻址,x,i,。,一般来说,循环工作部分中的数据应该用间接方式来寻址,如这里用:,ADD A,,,R0,计数控制,只有在,循环次数已知,的情况下才适用。,循环次数未知,,不能用循环次数来控制,往往,需要根据某种条件,来判断是否应该终止循环。,70,(,2,)条件控制结构,结构见,图,4-9,。循环控制中,设置一个条件,判是否满足该条件,如满足,则循环结束。如不满足该条件则循环继续。,【,例,4-13,】,一串字符,依次存放在内部,RAM,从,30H,单元开始的连续单元中,,字符串,以,0AH,为,结束标志,,测试,字符串长度,。,采用逐个字符依次与“,0AH,”比较(设置的条件)的方法。设置一个,累计,字符串长度的,长度计数器,和一个用于指定,字符串指针,。,如果字符与“,0AH,”,不等,,则,长度计数器,和,字符串指针,都加,1,;如果比较,相等,,则表示该字符为“,0AH,”,,字符串结束,,计数器值就是字符串的长度。程序如下:,71,MOVR4,,,#0FFH,;长度计数器初值送,R4,MOV R1,,,#2FH,;字符串指针初值送,R1,NEXT,:,INC R4,INC R1,CJNE R1,,,#0AH,,,NEXT,;比较,不等则进行下一,;字符比较,END,上面两例都是,在一个循环程序中不再包含其他循环程序,,则称该循环程序为,单循环程序,。如果,一个循环程序中包含了其他循环程序,,则称为,多重循环程序,。,最常见的多重循环是由,DJNZ,指令,构成的,软件延时程序,,是常用程序之一。,72,【,例,4-14,】,50ms,延时程序。,软件延时程序与指令执行时间有很大的关系,。在使用,12MHz,晶振,时,一个机器周期为,1s,,执行一条,DJNZ,指令的时间为,2s,。可用,双重循环方法,的延时,50ms,程序:,DEL,:,MOV R7,,,#200,;本指令执行时间,1s,DEL1,:,MOV R6,,,#125,;本指令执行时间,1s,DEL2,:,DJNZ R6,,,DEL2,;指令执行,1,次为,2s,,计,;,125,2 s=250s,DJNZ R7,,,DEL1,;指令执行时间,2s,,本循环体 ;执行,125,次,RET,;指令执行时间,2s,73,以上延时程序,不是太精确,,如把所有指令的执行时间计算在内,它的延时时间为,1+,(,1+250+2,),200+2,s,,,如要求,比较精确的延时,,应对上述程序进行修改,才能达到较为精确的延时时间。但要注意,用软件实现延时程序,,不允许有中断,,否则将严重影响定时的准确性。,对于延时更长的时间,可采用多重的循环,如,1s,延时,可用三重循环。,74,
展开阅读全文