《片机学习第四章汇编语言程序设计.ppt》由会员分享,可在线阅读,更多相关《片机学习第四章汇编语言程序设计.ppt(57页珍藏版)》请在三一办公上搜索。
1、第4章 汇编语言程序设计,计算机在完成一项工作时,必须按照顺序执行各项操作。这些操作是计算机程序设计人员按照解决问题的步骤事先描述好的算法,设计出相应的程序,然后由计算机去执行。程序设计就是用计算机所能接受的形式把解决问题的步骤描述出来。本章介绍汇编语言程序设计的基础知识,通过实例让学习汇编语言程序的设计方法。,本章总体要求:,熟练掌握汇编语言语句的格式、常用的伪指令和程序流程图,1,掌握汇编语言程序设计的步骤和技巧,2,熟悉顺序、分支、循环结构和子程序调用等程序的应用特征,3,能够独立完成本章作业,4,本章重点:,汇编语言程序设计中常用伪指令的使用,1,汇编语言程序设计的步骤,2,分支与循环
2、描述的理解与实现,3,综合程序的设计,4,本章难点:,汇编语言程序设计算法的确定及绘制程序流程图,1,多重循环程序设计及子程序设计与调用,2,综合应用程序设计的实现,3,4.1.1 程序设计语言1机器语言:机器语言是直接面向硬件的二进制代码指令。2汇编语言:汇编语言是机器语言的符号表示,与机器语言一一对应,编程效率高,实时性好,但也不能跨平台工作。3高级语言:高级语言是一种面向算法和过程的语言。,4.1 汇编语言简介,4.1.2 汇编语言格式,汇编语言语句格式为:标号:操作码 操作数;注释 1.标号是由用户定义的符号地址,指明该指令的起始地址。标号是由英文字母开头的18个字母和数字组成的字符串
3、,以冒号“:”结尾。,2操作码操作码表示该语句要执行的操作内容,是每一条汇编语言必有的部分。操作码用助记符表示,在操作码后面至少要有一个空格,使它与操作数分开。3操作数操作数是该指令操作所需要的数据。注意:这一字段可能有也可能没有,当多于一个操作数时,操作数之间用逗号分隔。,操作数字段的内容可以包括以下几项:(1)工作寄存器名;(2)特殊功能寄存器名;(3)标号名;(4)常数;(5)$:该符号用来表示程序计数器的当前值。该符号常出现在转移指令中;(6)表达式:在汇编时,计算出表达式的值,并把该值填入目标码中。,4注释注释不是汇编语言的功能部分,它是语句的说明部分,用于改善程序的可读性,它以分号
4、“;”开始。注释可为一行或多行(每行均以分号开始)。,4.1.3 伪指令 所谓伪指令又称为伪操作,它不象机器指令那样是在程序运行期间由计算机来执行的,它是在汇编程序对源程序汇编时,由汇编程序处理的操作,它们可以完成如数据定义、分配存储器、指示程序结束等功能。,1汇编起始地址命令 格式:ORG nn 功能:规定此命令之后的程序或数据的存放起始地址。ORG伪指令总是出现在每段源程序或数据块的开始。,2定义字节伪指令格式:标号:DB X1,X2,Xn功能:从指定地址开始,存放若干字节数据。注意:在程序存储器空间定义8位单字节数据,通常用于定义一个常数表。Xi为单字节数据,它为二进制、八进制、十进制或
5、十六进制数,也可以为一个表达式,还可以是由两个单引号所括起来的一个字符串,或单引号括起来的字符。,3字定义伪指令格式:标号:DW Y1,Y2,Yn功能:从指定地址开始,存放若干字数据。注意:在程序存储器空间定义双字节数据,经常用于定义一个地址表。Yi为双字节数据,它可以为十进制或十六进制的数,也可以为一个表达式。高位数在前,低位数在后。,例如:ORG 1000H DATA:DW 3241H,1234H,78H 上述程序将对从1000H单元开始的6个单元赋值,赋值情况如何呢?(1000H)=32H,(1001H)=41H,(1002H)=12H,(1003H)=34H,(1004H)=00H,(
6、1005H)=78H。,4汇编结束伪指令 END 该伪指令指出结束汇编,即使后面还有指令,汇编程序也不处理。5赋值伪指令格式:标号 EQU 表达式功能:将表达式的值(数据或地址)赋给标 号。,注意:标号为字符名称,其后无冒号。在一个程序中对于某一个标号只能赋一次值,一旦赋值在本程序的任意位置就可以引用该标号。例如:ORG 3000HSTAEQU 80HTABEQU 10MULEQU 4000HMOV A,STAMOV B,TABLCALL MUL,定义了三个标号:STA=80H,TAB=10,MUL=4000H,在程序中直接引用这三个标号来代替80H、10、4000H。,6位定义伪指令格式:标
7、号 BIT 位地址功能:将位地址赋给标号。其中,标号为字符名称,其后无冒号。例如:A1 BIT P0.1A2 BIT PSW.3,4.2 汇编语言程序设计,4.2.1 汇编程序设计基础1汇编语言程序设计的步骤:(1)分析问题,明确任务(2)确定算法(3)画出程序流程图(4)编写源程序(5)汇编和调试,2汇编语言程序的格式ORG 起始地址;数据存放;程序代码SJMP$;原地踏步END,3汇编语言源程序的汇编 汇编语言源程序必须转换成计算机能过识别的目标程序后才能执行,汇编方法通常有机器汇编和手工汇编两种方法。,4汇编语言程序设计的技巧(1)尽量采用模块化、结构化的程序设计方法。(2)合理地绘制程
8、序流程图(3)少用无条件转移指令,尽量采用循环结构和子程序结构。(4)充分利用累加器。(5)精心设计主要程序段。(6)对于中断要注意保护和恢复现场。,4.2.2 顺序程序设计 顺序结构程序又称为简单结构程序,是指一种顺序执行的程序,程序从第一条指令到最后一条指令的整个执行过程中既无分支又无循环。,【例4.1】两个8位无符号数相加,和仍为8位。分析:假设两个无符号数X、Y分别存放于内部RAM的60H、61H单元中,求和并存于62H单元中。程序如下:ORG 2000HMOVR0,#60H;设R0为数据指针MOVA,R0;将X值送入A中INCR0ADDA,R0;X+YINCR0MOVR0,A;保存结
9、果SJMP$;原地踏步END,【例4.2】假设两个双字节无符号数,分别存放在R1R0和R3R2中,高字节在前,低字节在后。编程使两数相加,用R2R1R0存放和。对多字节的加法,存在最高位的进位问题。如果最高位有进位,则和的字节数要比加数或被加数的字节数多一个。,ORG 1000HCLR CMOV A,R0;取被加数低字节AADD A,R2;与加数低字节相加MOV R0,A;存和数低字节MOV A,Rl;取被加数高字节AADDC A,R3;与加数高字节相加MOV R1,A;存和数高字节MOV A,#0ADDC A,#0;加进位位MOV R2,A;存和数进位位SJMP$;END,【例4.3】16位
10、二进制数求补,设两个字节原码数存在R1R0中,求补后结果存在R3R2中。分析:二进制数求补操作,可采用“原码求反+1”的方法来实现,可使用求反指令和加法指令来实现。,程序如下:ORG 1000HMOVA,R0;低8位送ACPLA;ADDA,#01H;MOVR2,A;送结果低位MOVA,R1;高8位送ACPLA;ADDCA,#00H;加进位MOVR3,A;送结果高位SJMP$END,【例4.4】将内部RAM的60H单元中的无符号二进制数转换为3位BCD码,并将结果按由高位到低位的顺序存放到63H、62H、61H单元中。分析:8位无符号二进制数表示的数据范围0255,所以用BCD码,最多3位。可将
11、被转换的数除以100,商即百位数;余数再除以10得十位数;最后余数即为个位数。,编程如下:ORG 1000HHBCD:MOV A,60H;取原数据MOV B,#100;除数100BDIV AB;除100MOV 63H,A;百位BCDMOV A,BMOV B,#10;除数10BDIV AB;MOV 62H,A;存十位BCD MOV 61H,B;存个位BCDSJMP$END,4.2.3 分支程序设计,图4-1 分支程序流程图,【例4.5】设内部RAM 60H和61H单元中存放两个无符号数,试比较它们的大小。将较小的数存放在60H单元,较大的数存放在61H单元中。分析:这是一个简单分支程序,可以使两
12、数相减,用JC指令进行判断。若CY=1,则被减数小于减数。,ORG1000HSTART:CLR C;0CY MOVA,60H SUBBA,61H;做减法比较两数 JC NEXT;若(60H)小,则转移 MOVA,60H XCH A,61H;交换两数 MOV 60H,A NEXT:NOP SJMP$END,【例4.6】将R2中的一位十六进制数转换为ASCII码,结果仍存放于R2中。分析:数字09的ASCII码分别是30H39H,英文大写字母AF的ASCII码分别是4146H。因此,若该十六进制数小于10,要转换为ASCII码应加30H,若该十六进制数大于10,则加37H。,ORG 1000HMO
13、V A,R2CJNE A,#0AH,L1L1:JNC ADD37ADD30:ADD A,#30HMOV R2,ASJMP FINISHADD37:ADD A,#37HMOV R2,AFINISH:SJMP$END,【例4.7】设变量x存入30H单元,求得函数y存入31H单元。按下式要求给y赋值:x+1(1010时,采用CJNE和JC以及CJNE和JNC指令进行判断。,程序如下:ORG 1000HMOV A,30H;取XCJNE A,#5,NEXTl;与5比较NEXT1:JC NEXT2;X10,则转NEXT4 MOV R0,#0;5X10,Y=0 SJMP NEXT4NEXT2:MOV R0,
14、A DEC R0;X5,Y=X-1NEXT4:MOV 31H,R0;存结果SJMP$END,4.2.4 循环程序设计循环程序一般包括以下5部分:初始化部分:循环程序的准备部分,把初始参数赋给控制变量。循环处理部分:循环程序反复执行的部分,这是循环程序的实体。修改部分:修改控制变量的值,为进入下一轮循环做准备。控制部分:根据循环结束条件,判断循环是否结束。结束部分:分析、处理及存放程序执行结果。,循环程序的结构一般由两种形式:,1单循环程序设计【例4.8】循环次数已知的单重循环。在内部RAM的 20H2FH连续16个单元中存放单字节无符号数。求这16个无符号数之和,并存入内部RAM 61H和60
15、H中。分析:这是重复相加问题,且事先知道循环次数,故采用计数器控制的循环程序设计方法。设用R0作加数地址指针,R7作循环次数计数器,R3作和数的高字节寄存器。,ORG 0200HSTART:MOV R7,#15;循环次数 MOV R3,#0;装和的高字节MOV A,20H;MOV R0,#21H;加数的地址 LOOP:ADD A,R0;累加和在A中 JNC NEXT;没进位则跳NEXT INC R3;有进位,则高位加1 NEXT:INC R0;加数地址加1 DJNZ R7,LOOP MOV 61H,R3;将和的高位传51H中MOV 60H,A;将和的低位传50H中SJMP$END,【例4.9】
16、循环次数未知的单重循环。设有一字符串存放在内部RAM 21H开始的单元中,并以“$”作为结束标志,请计算该字符串的长度,并将其存入20H单元。分析:该字符串长度事先未知,但知道结束条件,故采用条件控制的循环程序设计方法。,程序如下:ORG 0200HMOVA,#0MOVR0,#21HLOOP:CJNER0,#24H,NEXTSJMPEXITNEXT:INCAINCR0SJMPLOOPEXIT:MOV20H,ASJMP$END,2多重循环程序设计【例4.11】设单片机使用12MHz晶振(机器周期T为1s),设计延时1s的程序。分析:因为执行每条指令都需要一定的时间,其时间长短由指令周期和晶振频率
17、决定(t=机器周期数12振荡周期)。单条指令的执行时间只有1到几个微秒,若需要较长时间的延时就需要执行多条指令,在单片机应用中一般采用多重循环方式来实现。,程序如下:ORG200HDEL1s:MOVR3,#10;单周期,1TDEL1:MOVR4,#200;单周期,1TDEL2:MOVR5,#248;单周期,1TDEL3:DJNZR5,DEL3;双周期,2TNOP;单周期,1TDJNZR4,DEL2;双周期,2TDJNZR3,DEL1;双周期,2TRET;双周期,2TEND,【例4.12】将片内RAM 40H4FH单元的16个无符号数按从大到小的顺序排列,排序后仍存放在原数据区中。分析:这是一个
18、数据排序问题。数据排序常用的方法有“冒泡法”和“选择法”。下面采用“冒泡法”设计程序。所谓“冒泡法”是指依次将两个相邻单元的内容进行比较,如果符合由大到小的顺序,数据保持原状,否则相邻单元的数据互换。经过一轮比较以后,这一组数中最小的数已经找出,存放于数据区的最后位置。然后再进行第二轮的比较,循环结束时找出次小数。继续循环,直到原数据区中存放的是从大到小的排序的数组。,例4.12程序流程图,ORG1000HSORT:MOV R0,#40H;置数组首地址MOVR7,#10H;数据块长度CLRF0;交换标志清0DECR7;循环次数SORT1:MOV A,R0;取前数MOV20H,A;把前数暂存在2
19、0H单元INCR0MOV21H,R0;后数暂存于21H单元CJNEA,21H,SORT2;相邻两数比较SORT2:JNC SORT3;若前数大于等于后数,转SORT3MOVA,R0;若前数小于后数,两者交换MOVR0,20HDECR0MOVR0,AINCR0;恢复R0原值SETBF0;置交换标志位为1SORT3:DJNZ R7,SORT1;如计数器长度不为0,则继续比较JB F0,SORT;若判断标志位为1,则继续循环,否结束循环SJMP$END,注意:对于循环结构程序设计,需要注意:(1)在进入循环之前,应合理设置循环初始变量。(2)循环体只能执行有限次,如果无限执行的话,称之为“死循环”,
20、这是应当避免的。(3)不能破坏或修改循环体,要特别注意的是避免从循环体外直接跳转到循环体内。(4)多重循环的嵌套是从外层向内层一层层进入,从内层向外层一层层退出。不要在外层循环中用跳转指令直接转到内层循环休内。(5)循环体内可以直接转到循环体外或外层循环中,实现一个循环由多个条件控制结束的结构。(6)对循环体的编程要仔细推敲,合理安排,对其进行优化时,应主要放在缩短执行时间上,其次是程序的长度。,4.2.5 子程序调用设计1子程序的结构 在MCS-51指令系统中,提供了两条子程序指令ACALL、LCALL以及一条返回主程序的指令RET。一个子程序在运行的过程中还可以调用其它的子程序,这称为子程
21、序嵌套。,2子程序设计时的注意事项(1)每个子程序都应有唯一的入口,子程序的第一条指令的地址称为入口地址。该指令前必须有标号,最好以子程序的任务定名,以便主程序正确的调用它。(2)调用子程序的指令在主程序中,子程序以RET指令结束,这样才能返回主程序。(3)子程序调用和返回指令能自动保护和恢复断点,但对于需要保护的寄存器和内存单元的内容,必须在子程序开始和末尾安排保护和恢复他们的指令。(4)为使所编的子程序可以放在64KB程序存储器的任何地方并能被主程序调用,子程序内部必须使用相对转移指令而不使用其它转移指令,以便汇编时生成浮动代码。,3参数传递方法 在调用子程序时会遇到主程序和子程序之间参数
22、如何传递的问题。入口参数:主程序调用子程序时,传入子程序的参数称为入口参数。出口参数:子程序运算出的结果称为出口参数。常用的参数传递方法有:工作寄存器或累加器、指针寄存器、堆栈和程序段等。,【例4.13】用子程序调用的方法实现C=a2+b2,假设a、b均小于10。a存于31H单元,b存于32H单元,结果C存于30H单元。分析:因为a、b均小于10,则它们的平方和为单字节数,因为本题两次用到平方的运算,所以把求平方运算设计成子程序。,子程序和主程序如下:ORG1000HMAIN:MOV SP,#60H;设置堆栈指针MOVA,31H;取a的值LCALL SQR;调子程序,求a2MOV30H,A;a
23、2存储于30H单元MOVA,32H;取b的值LCALL SQR;调子程序,求b2ADDA,30H;求a2+b2MOV30H,A;结果存于30H单元SJMP$ORG2000HSQR:MOVB,A;求平方子程序MULABRET END,4.3 综合程序设计,【例4.15】求Y=n!(n=0,1,2,9)的值。分析:如果按照求阶乘的运算,程序设计十分繁琐,需连续做n-1次乘法。但如果将函数值列成表格,每个函数值占用3个字节的存储单元,则每个n值所对应的y值在表格中的地址可按下面公式计算出来。Y地址=函数表首址+n3 因而可采用计算查表法。对每一n值,首先按上述公式计算出对应于y的地址,然后从该单元中
24、取出y值。设:n值存放在TEM单元,表的首址为TABL,用MOVC A,A+DPTR指令查表取出Y值存入R2R1R0中。,程序如下:ORG2000H TEM EQU 30HCALN:MOV A,TEM;取n值 MOV B,#3 MUL AB;n 3A MOV B,A;暂存B中 MOV DPTR,#TAB;指向表首址TABL MOVC A,A+DPTR;查表取低字节 MOV R0,A;存入R0 INC DPTR;修正地址指针,MOV A,B;恢复n 3 MOVC A,A+DPTR;查表取中间字节MOV R1,A;存入R1 INC DPTR;修正地址指针MOV A,B;恢复n 3 MOVC A,A十DPTR;查表取高字节MOV R2,A;存入R2 RET ENDTABL:DB 00,00,00;0的阶乘DB 01,00,00;1的阶乘,本 章 小 结,1汇编语言的格式:标号:操作码 操作数;注释2伪指令又称伪操作,它是在汇编程序对源程序汇编时,由汇编程序完成入数据定义、分配存储器、指示程序结束等操作。3汇编语言程序设计一般要经过分析问题、确定算法、画出程序流程图、编写源程序、汇编和调试等5个步骤。4汇编语言程序基本结构顺序程序、分支程序、循环程序、子程序。一个真正的应用程序往往不是单纯的一种结构,而是几种结构混合使用。,