第4章:汇编语言程序设计4.1汇编语言程序概述4.1.1源程序的编辑和汇编4.1.2伪指令4.1.3汇编语言程序设计步骤4.2汇编语言程序设计4.2.1顺序程序设计4.2.2分支程序设计4.2.3循环程序设计4.3子程序及其调用4.3.1子程序的设计注意事项4.3.2参数传递目录本节内容4.1.1源程序的编辑和汇编4.1.2伪指令4.1.3汇编语言程序设计步骤4.1汇编语言程序概述44.1汇编语言程序概述4.1.0单片机编程语言常用的编程语言是汇编语言和高级语言。1.汇编语言汇编语言:用助记符表示的指令。汇编语言源程序:用汇编语言编写的程序。优点:用汇编语言编写程序效率高,占用存储空间小,运行速度快,能编写出最优化的程序。缺点:可读性差,是面向“硬件”的语言,离不开具体的硬件,通用性差,程序不易移植。54.1汇编语言程序概述2.高级语言经过十几年努力,C51已成为单片机的实用高级编程语言。优点:不受具体“硬件”的限制,通用性强,直观、易懂、易学,可读性好。缺点:高级语言编写的程序经编译后所产生的目标程序大,占用内存多,这在实时应用中是一个突出的问题。注意:目前多数的51单片机用户使用C语言(C51)来进行程序设计,已公认为高级语言中高效简洁而又贴近51单片机硬件的编程语言。尽管目前已有不少设计人员使用C51来进行程序开发,但在对程序的空间和时间要求较高的场合,汇编语言仍必不可少。掌握汇编语言并能进行程序设计,是学习和掌握单片机程序设计的基本功之一。64.1汇编语言程序概述4.1.1源程序的编辑和汇编为了克服机器语言难读、难记忆的缺点,人们采用英文字符来代替这些机器码,这些英文字符被称作助记符。用助记符表示的指令称为汇编语言。用汇编语言编写程序的过程称为汇编语言的程序设计。汇编语言程序只有转变成二进制的机器语言单片机才能认识和执行。同常把这一“翻译”过程称为编译汇编。能够完成这一翻译过程的软件称为汇编程序或编译器。经过编译或汇编得到的能够下载(烧录)到单片机中的0、1的代码称为目标程序。7一、源程序的编辑现在单片机应用系统的程序编辑工作几乎都借助于个人PC机来完成。Keil或WAVE等集成开发环境都具有编辑功能。编写好的汇编语言源程序应以“*.ASM”扩展名存盘,以备编译器调用。4.1汇编语言程序概述8二、源程序的汇编将汇编语言源程序转换为机器码这个转换过程称为汇编或编译,能完成该转换功能的软件称为编译器。汇编常用的方法有两种:一是手工汇编,二是机器汇编。①手工汇编时,把程序用助记符指令写出后,人为查找指令代码表,逐个把助记符指令翻译成机器码。②机器汇编是在计算机上使用编译软件对源程序进行汇编。整个工作由PC机来完成,且最后生成一个“*.HEX”或“*.BIN”机器码形式的目标程序文件。编译之后的目标程序,可以通过专门的下载(烧录)软件,把它由计算机传入单片机ROM当中。4.1汇编语言程序概述本节内容4.1.1源程序的编辑和汇编4.1.2伪指令4.1.3汇编语言程序设计步骤4.1汇编语言程序概述104.1.2伪指令指令:能使CPU执行某种操作,能生成对应的机器代码。伪指令是程序员发给编译器的命令,“伪”表示其不能命令CPU执行某种操作,也没有对应的机器代码,它的作用仅用来给汇编程序提供某种信息。伪指令也称为编译器的控制命令,具有控制汇编程序的输入/输出、定义数据和符号、分配存储空间等功能。4.1汇编语言程序概述11一、汇编起始伪指令ORG格式:[标号:]ORG16位地址(符号地址也可)功能:规定程序块或数据块存放的起始地址。例如:ORG8000HSTART:MOVA,#30H……该伪指令规定第一条指令在ROM中从地址8000H单元开始存放,即标号START的值为8000H。4.1汇编语言程序概述12通常,在一个汇编语言源程序的开始,都要设置一条ORG伪指令来指定该程序在存储器中存放的起始位置。若省略ORG伪指令,则该程序段从0000H单元开始存放。在一个源程序中,可以多次使用ORG伪指令,以规定不同程序段或数据段存放的起始地址,但在源程序中,要求16位地址值由小到大顺序排列,且不允许空间重叠。例如:ORG2000H……ORG2500H……ORG3000H4.1汇编语言程序概述13这种顺序是正确的。若按下面的顺序排列则是错误的,因为地址出现了交叉。ORG2500H……ORG2000H……ORG3000H4.1汇编语言程序概述14二、汇编结束伪指令END格式:[标号:]END[表达式]功能:结束汇编。说明:汇编程序遇到END伪指令后即结束汇编。处于END之后的源程序将不被汇编。该指令在源程序的最后一行,且只能在程序中出现一次。4.1汇编语言程序概述15三、字节数据定义伪指令DB格式:[标号:]DB8位字节数据表功能:从标号指定的地址单元开始,将数据表中的字节数据按顺序依次存入。例如:ORG1000HTAB:DB-2,-4,100,30H,‘A’,‘C’……4.1汇编语言程序概述16例如:ORG1000HTAB:DB-2,-4,100,30H,‘A’,‘C’……注意:数据表可以是一个或多个字节数据、字符串或表达式,各项数据用“,”分隔,一个数据项占一个存储单元。汇编后:(1000H)=0FEH,(100lH)=0FCH,(1002H)=64H,(1003H)=30H,(1004H)=41H,(1005H)=43H。用单引号括起来的字符以ASCII码存入,负数用补码存入。4.1汇编语言程序概述17四、字数据定义伪指令DW格式:[标号:]DW16位字数据表功能:从标号指定的地址单元开始,将数据表中的字数据按从左到右的顺序依次存入程序存储器中。注意:16位数据存入时,先存高8位,后存低8位。例如:ORG1400HDATA:DW324AH,3CH……汇编后:(1400H)=32H,(1401H)=4AH,(1402H)=00H,(1403H)=3CH4.1汇编语言程序概述习题ORG2000HDB‘$’,20,-7DW4AH,1200H……汇编后:(2000H)=(),(2001H)=(),(2002H)=(),(2003H)=(),(2004H)=(),(2005H)=(),(2006H)=(),(2007H)=()。4.1汇编语言程序概述19五.赋值伪指令EQU格式:符号名EQU常值表达式或符号名=常值表达式功能:将表达式的值定义为一个指定的符号名。LENEQU10HSUNEQU41HBLOCKEQU22HCLRAMOVR7,#LENMOVR0,#BLOCKLOOP:ADDA,@R0INCR0DJNZR7,LOOPMOVSUN,A该指令的功能是把22H单元开始存放的16个数进行求和,并将结果送入41H单元。注意:用EQU定义的符号不允许重复定义,用“=”定义的符号允许重复定义。4.1汇编语言程序概述20六、定义位地址为符号名伪指令BIT格式:符号名BIT位地址该指令的功能是将位地址赋给指定的符号名。位地址表达式可以是绝对地址,也可以是符号地址。如:STBITP1.0;将P1.0的位地址赋给符号名STCFBIT0D7H;将位地址为D7H的位定义为符号名CF注意:用BIT定义的“符号名”不允许重复定义。4.1汇编语言程序概述本节内容4.1.1源程序的编辑和汇编4.1.2伪指令4.1.3汇编语言程序设计步骤4.1汇编语言程序概述224.1.3汇编语言程序设计步骤使用汇编语言设计一个程序大致上可分为以下几个步骤。(1)分析题意,明确要求。(2)确定算法。(3)画程序流程图,用图解来描述和说明解题步骤。(4)分配内存工作单元,确定程序与数据区存放地址。(5)编写源程序。(6)程序优化。(7)上机调试、修改和最后确定源程序。4.1汇编语言程序概述本节内容4.2.1顺序程序设计4.2.2分支程序设计4.2.3循环程序设计4.2汇编语言程序设计4.2汇编语言程序设计24汇编语言程序共有四种结构形式,即:顺序结构、分支结构、循环结构和子程序结构。4.2.1顺序程序设计顺序结构程序是一种最简单、最基本的程序(也称为简单程序),它是一种无分支的直线形程序,按照程序编写的顺序依次执行。【例4-2】设一个2位十进制数的十位数字以ASCII码的形式存放在片内RAM的31H单元,32H单元存放该数据个位的ASCII码。编写程序将该数据转换成压缩BCD码存放在20H单元。25解:由于ASCII码30H~39H对应BCD码的0~9,所以只要保留ASCII的低4位,而高4位清零即可。实现程序如下:ORG0040HSTART:MOVA,31H;取十位ASCII码ANLA,#0FH;保留低半字节SWAPA;移至高半字节MOV20H,A;存于20H单元MOVA,32H;取个位ASCII码ANLA,#0FH;保留低半字节ORL20H,A;合并到结果单元SJMP$4.2汇编语言程序设计本节内容4.2.1顺序程序设计4.2.2分支程序设计4.2.3循环程序设计4.2汇编语言程序设计图(a)结构是用条件转移指令来实现分支。当给出的条件成立时,执行程序段A,否则执行程序段B。图(b)结构是用散转指令JMP来实现多分支转移。它首先将分支程序按序号排列,然后按照序号的值来实现多分支转移。4.2.2分支程序设计分支程序的结构有两种,如图所示:4.2汇编语言程序设计28分支程序的特点:改变程序的执行顺序,跳过一些指令,去执行另外一些指令。注意:对每个分支都要单独编写一段程序,每一分支的开始地址赋给一个标号。一、单分支选择结构程序的判别仅有两个出口,两者选一,称为单分支选择结构,它在程序设计中的应用极为普遍。4.2汇编语言程序设计29【例4-3】求单字节有符号数的二进制补码,设待求数据存放于累加器A中。解:正数补码是其本身,负数补码是其反码加1。因此,程序应首先判断被转换数的符号,负数进行转换,正数本身即为补码。参考程序如下:CMPT:JNBACC.7,RETU;(A)0,不需转换MOVC,ACC.7;符号位保存CPLA;(A)求反,加1ADDA,#1MOVACC.7,C;符号位存在A的最高位RETU:RET4.2汇编语言程序设计30二、多分支选择结构当程序的判别部分有两个以上的出口流向时,为多分支选择结构。指令系统提供了非常有用的两种多分支选择指令:间接转移指令:JMP@A+DPTR比较转移指令:CJNEA,direct,relCJNEA,#data,relCJNERn,#data,relCJNE@Ri,#data,rel间接转移指令“JMP@A+DPTR”由数据指针DPTR决定多分支转移程序的首地址,由累加器A的内容动态地选择对应的分支程序。4条比较转移指令CJNE能对两个欲比较的单元内容进行比较。当不相等时,程序实现相对转移,并能指出其大小,以备进行第二次判断;若两者相等,则程序按顺序往下执行。4.2汇编语言程序设计31【例4-4】已知40H单元内有一自变量X,其以补码的形式存放,按如下条件编写程序求Y的值,并存入41H单元。4.2汇编语言程序设计解:X是有符号数,因此可以根据它的符号位来决定其正负,判别符号位是0还是1可利用JB或JNB指令。而判别X是否等于0则可以直接使用累加器判零JZ指令。32解:ORG2000HXY:MOVA,40H;A←(40H)JZDONE;X=0,转DONEJNBACC.7,POS;X0,转POSMOVA,#0FFH;X0,A←-1的补码SJMPDONE;转DONEPOS:MOVA,#01H;A←+1DONE:MOV41H,A;存Y值RET4.2汇编语言程序设计例:设5AH单元中有一整数X,请编写计算下述函数式的程序,结果存入5BH单元。X2-1(X10)Y=X2+8(10≤X≤15)41(X15)解:根据题意首先计算X2,并暂存于R1中,因为X2最大值为225,故只用一个寄存器,然后根据X值的范围,决定Y的值。在判断A10和A15时,采用CJNE、JC指令相结合以及CJNE、JNC指令相结合的方法程序流程图如图4-4