《[工学]第三章程序设计.ppt》由会员分享,可在线阅读,更多相关《[工学]第三章程序设计.ppt(35页珍藏版)》请在课桌文档上搜索。
1、,4-1 汇编程序的约定,4-2 程序设计步骤,4-3 直线程序,4-4 分支程序,4-5 循环程序,4-6 子程序,第四章 汇编语言程序设计,4-1 汇编程序的约定,汇编程序:能将汇编语言的源程序转换成机器语言的目标程序的一种系统软件,汇编:汇编语言程序到机器语言程序的转换过程1.手工汇编:人工查指令表,查出程序中每条指令对应的机器代码。用于设计短小程序或调试程序的场合2.机器汇编:用计算机中的汇编程序对用户源程序进行汇编。用机器汇编要考虑汇编程序的约定,汇编的主要任务:,1)确定程序中每条汇编语言指令的指令机器码2)确定每条指令在存储器中的存放地址,一.汇编语言指令类型,3)提供错误信息4
2、)提供目标执行文件(*.OBJ/*.HEX)和列表文件(*.LST),1.机器指令:指令系统中的全部指令。每条机器指令都有对应的机器代码,可以被CPU执行2.伪指令:汇编控制指令,没有指令代码,只用于汇编过程(预编译指令),为汇编程序提供汇编信息,地址 机器码源程序 ORG 2000H 2000H 78 30 MAIN:MOV R0,#30H 2002H E6 MOV A,R0,3.宏指令,宏汇编功能:将需要反复多次执行的程序段定义成一个宏指令名(宏定义)。编程时,可在程序中使用宏指令名来替代被定义的程序段(宏调用),宏定义过程:,宏调用过程:宏指令名 实际参数 宏指令名 实际参数,宏指令名
3、MACRO 形式参数;被定义的程序段 ENDM,用机器汇编要考虑汇编程序的约定,1)按指令格式和语法规则编写程序,常数表示法:十进制数:20,20D十六进制数:87H,0F0H二进制数:01011001B字符:H字符串:“Hello”,2)使用伪指令提供汇编信息,二伪指令 常用伪指令及功能:,1.ORG起始地址指令。定义程序或数据的起始地址指令地址 机器码源程序 ORG 2000H 2000H 78 30 MAIN:MOV R0,#30H 2002H E6 MOV A,R0,ORG 3000H 3000H 23 TAB:DB 23H,100,A 3001H 64 3002H 41,2.DB 定
4、义字节常数指令。输入程序中的常数例:DB 23H,100,ADB“HELLO”,4.EQU 等值指令。为标号或标识符赋值 X1 EQU 2000HX2 EQU 0FH MAIN:MOV DPTR,#X1 ADD A,#X2,5.END 结束汇编指令例:START:END START,3.DW 定义字型常数指令例:DW 1234H,5678H,4-2 汇编语言程序设计步骤,一.确定方案和计算方法二.了解应用系统的硬件配置、性能指标三.建立系统数学模型,确定控制算法和操作步骤四.合理分配存储器单元和了解I/O接口地址,五.编制源程序1.按功能设计程序,明确各程序之间的相互关系2.用流程图表示程序结
5、构和功能,3.程序中用注释说明指令在程序中的作用,方便阅读、调试和修改,常用程序结构直线程序、分支程序、循环程序、子程序,4-3 直线程序直线程序(简单程序),程序走向只有一条路径,双字节变补程序(设数据在R4R5中),MOV A,R5;取低字节CPL AADD A,#1;低字节变补MOV R5,AMOV A,R4;取高字节CPL AADDC A,#0;高字节变补MOV R4,A,例4-3-4 压缩式BCD码分解成为单字节 BCD码(拆字),MOV R0,#40H;设指针MOV A,R0;取一个字节MOV R2,A;暂存ANL A,#0FH;清0高半字节INC R0MOV R0,A;保存数据个
6、位,MOV A,R2SWAP A;十位换到低半字节ANL A,#0FHINC R0MOV R0,A;保存数据十位,0000个位,0000十位,MOV A,R2 JNB ACC.7,N;为正数?CPL A;负数变补 INC A MOV R2,AN:SJMP N;结束,4-4 分支程序由条件转移指令构成程序判断框部分,形成分支结构,4-4-2 单重分支程序一个判断决策框,形成一个分支两条出路。两种分支结构:,例 求8位补码的绝对值:正数不变,负数变补,每10kg为1个计价单位G已存入40H单元。行李运费计算:当G5,M=G3;当G5,M=G3+(G-5)(5-3),FRT:MOV A,40H;取行
7、李重量计价单位G MOV R3,A MOV B,#03H;运费M=G3 MUL AB MOV R2,A;暂存3G,MOV A,R3;取回G CJNE A,#05H,L1;G 5?SJMP WETCL1:JC WETC;是,转至WETC SUBB A,#05H;否则 M=3G+2(G-5)RLC A ADD A,R2 MOV R2,AWETC:MOV 41H,R2;存运费 M RET,4-4-3 多重分支程序一多次使用条件转移指令,形成两个以上判断框,例 求符号函数 Y=SGN(X)+1 当 X 0SGN(X)=0 当 X=0 1 当 X 0,SYMB:MOV A,40H;取X JZ STOR;
8、X=0,Y=X JB ACC.7,MINUS;X0 MOV A,#1;X0,Y=+1 SJMP STORMINUS:MOV A,#0FFH;X0,Y=1STOR:MOV 41H,A;保存Y RET,MOV A,R2 INC A MOVC A,A+DPTR;取分支地址 PUSH ACC;保存分支地址高8位 RET;分支地址PC,转移,二按分支号X转移:当 X=0,程序转移到 ADDR0处;当 X=1,程序转移到 ADDR1处;,MTJS:MOV DPTR,#TAB;取表首地址 ADD A,A;X2 MOV R2,A MOVC A,A+DPTR;取分支地址 PUSH ACC;保存分支地址低8位,(
9、1)用地址表法:设分支号 X 已存入 A累加器,TAB:DW ADDR0;分支地址表 DW ADDR1 ADDR0:;程序段 0 ADDR1:;程序段 1,ADD A,DPH;DPHDPH+(R7、R6)3)高字节 MOV DPH,A XCH A,B;A(R7、R6)3)低字节 JMP A+DPTR;实现多分支转移,MOV A,R6;X 低字节3 MOV B,#03H MUL AB XCH A,B,(2)转移表法 分支转移指令JMP A+DPTR,MTJS:MOV DPTR,#TAB;指向表首 MOV A,R7;X 高字节3 MOV B,#03H MUL AB;DPH乘积+DPH ADD A,
10、DPH MOV DPH,A,TAB:LJMP ADDR0;转移表 LJMP ADDR1 LJMP ADDRNADDR0:;程序段0,设R7R6=X(分支号),4-5 循环程序包含多次重复执行的程序段,循环结构使程序紧凑,4-5-1循环程序的构成,各个环节任务:一初始化部分:循环准备工作如:清结果单元、设数据指针、设循环控制变量的初值等,二循环体循环工作部分:需多次重复处理的工作循环控制部分:,1.修改数据指针,修改循环控制变量2.检测循环条件:满足循环条件,继续循环,否则退出循环,三.结束部分 处理和保存循环结果,循环工作至少执行一次的循环结构允许 0 次循环的结构:在循环工作之前检测循环条件
11、,4-5-2 单重循环简单循环结构:循环体中不套循环,例:求n个单字节数据的累加,设数据串已在43H起始单元,数据串长度在42H单元,且累加和不超过2个字节,SUM:MOV R0,#42H;设数据指针 R0 MOV A,R0 MOV R2,A;设循环计数器 R2n CLR A;结果单元清0 MOV R3,A,ADD1:INC R0;修改数据指针 ADD A,R0;累加 JNC NEXT;处理进位 INC R3;有进位,高字节加1NEXT:DJNZ R2,ADD1;循环控制:数据全部加完?MOV 40H,A;循环结束:保存结果 MOV 41H,R3 RET,循环控制方法:计数控制、特征控制,一.
12、计数控制 设循环计数器,控制循环次数,有正计数和倒计数两种方式例:为一串7位ASCII码加奇校验(D7=0),设ASCII码数据串已存放在片外RAM的2101H起始单元,数据长度在2100H单元,MOV DPTR,#2100H;设指针 MOVX A,DPTR MOV R2,A;设计数器NEXT:INC DPTR;修改指针 MOVX A,DPTR;取ASCII码 ORL A,#80H;加奇校验位 JNB P,PASS;不符合奇校验?转移 MOVX DPTR,A;修改数据PASS:DJNZ R2,NEXT;已处理全部数据?DONE:SJMP DONE,二.特征控制:设定循环结束标志实现循环控制,例
13、:找正数表中的最小值,设正数表已存放在片外RAM中以LIST为起始单元,用-1作为结束标志,START:MOV DPTR,#LIST;数据表首地址 MOV B,#127;预置最小值NEXT:MOVX A,DPTR;取数 INC DPTR;修改指针 CJNE A,#-1,NEXT1;是否为结束标志?SJMP DONE;循环结束NEXT1:CJNE A,B,NEXT2;找较小值NEXT2:JNC NEXT MOV B,A;保存较小值 SJMP NEXT;循环DONE:SJMP DONE,习题1统计某班单科考试为100分和不及格人数,设成绩单已存放杂在片内RAM 起始地址为41H的连续单元中,4-5
14、-3 多重循环循环体中套循环结构。以双重循环使用较多,例 将内存中单字节无符号数串升序排序 双重循环,每次取相邻两个单元的数据比较,决定是否需要交换数据位置冒泡排序法步骤:,第一次内循环,比较N-1次,取数表中最大值第二次内循环,比较N-2次,取到次大值,第N-1次内循环:比较一次排序结束,由外循环计数器决定内循环次数;内循环计数器决定比较次数,SORT:MOV A,#N-1;N个数据排序 MOV R4,A;外循环次数LOOP1:MOV A,R4 MOV R3,A;内循环次数 MOV R0,#TAB;设数据指针LOOP2:MOV B,R0;取相邻单元数据 INC R0 MOV A,R0 CJN
15、E A,B,L1;比较 L1:JNC UNEX;AB,不交换 DEC R0;相邻单元交换 XCH A,R0 INC R0 MOV R0,AUNEX:DJNZ R3,LOOP2;内循环结束?DJNZ R4,LOOP1;外循环结束?RET,软件延时程序用循环程序将指令序列重复多次执行,实现软件延时,例:试计算下面软件延时程序的执行时间 源程序 指令周期(M)指令执行次数,DELAY:MOV R6,#64H1 I1:MOV R7,#0FFH1 I2:DJNZ R7,I22 DJNZ R6,I12 RET2,延时时间计算:(设时钟频率fosc=12MHz,则机器周期 M=1s)t=(11+1100+2
16、100255+2100+21)M=1+100+51000+200+2=51303 s=51.3 ms,11001002551001,设计软件延时程序时,延时时间主要决定于内循环中指令序列的循环次数,习题2,1.试计算延时程序的执行时间(设时钟频率fosc=6MHz)源程序 指令周期(M)指令执行次数,DELAY:MOV R6,#1001 MOV R7,#01 D1:NOP1 DJNZ R7,D12 DJNZ R6,D12 RET2,习题3将内存中单字节无符号数据串进行降序排序,4-6 子程序 能完成某项特定功能的独立程序段,可被反复调用执行,4-6-1 子程序设计一子程序入口用标号作为子程序名
17、二调用子程序之前设置好堆栈三用返回指令RET结束子程序,并保证堆栈栈顶为调用程序的返回地址四.子程序嵌套要考虑堆栈容量五.提供足够的调用信息:子程序名、子程序功能、入口参数和出口参数、子程序占用的硬件资源、子程序中调用的其他子程序名,子程序调用指令:LCALL 子程序名或:ACALL 子程序名子程序返回指令:RET,4-6-4 子程序的类型按子程序与调用程序之间传递参数的方式分类,入口参数:调用子程序之前,调用程序传给子程序的参数出口参数:子程序送回调用程序的结果参数,几种参数传递方式:1.寄存器传送参数2.存储器传送参数3.堆栈传送参数,设计子程序应满足通用性的要求,不能针对常数编程例:1.
18、子程序功能为求单字节数的立方:B、AA3,入口参数:A,出口参数:A、B 2.子程序功能为求单字节数的n次方(41H)(42H)(40H)A 入口参数:(40H)和 A,出口参数:(42H)(41H),PMT:MOV R2,A;取数串长度CHC:MOV A,R0;分别取两个数串中的数据 MOV 42H,R1 CJNE A,42H,N;相等?不相等转移 INC R0;相等,修改指针 INC R1 DJNZ R2,CHC;全部比较完?MOV A,#0;设完全相等标志:A=0 SJMP P N:MOV A,#0FFH;设不完全相等标志:A=FFHP:RET,例 比较两个数据串是否完全相等,若完全相等
19、,A=0;否则 A=FFH,程序入口参数:A、R0、R1 出口参数:A,例:将R4R5R6中三个字节数据对半分解,变成6个字节,存入片内RAM的显示缓冲区(DISMEM0DISMEM5),UFOR1:MOV R0,#0 XCHD A,R0;保存低半字节 INC R0;修改指针 MOV R0,#0 SWAP A XCHD A,R0;保存高半字节 RET,1)UFOR1子程序的功能:将A累加器中单字节数据,对半分解成两个字节,存入R0指向的相邻两个单元2)入口参数:将待分解的内容送 A,片内RAM的存放地址送R0,例:查表求出数据的ASCII码,以字符形式输出,1)子程序HEXASC功能:取出堆栈
20、中数据,查表将低半字节转换成ASCII码送累加器 A2)分别将待转换数据入栈,然后调用子程序 HEXASC,MOV SP,#30H PUSH 40H;入口参数入栈 LCALL HEXASC POP AHEXASC:DEC SP;跳过返回地址 DEC SP POP A;取入口参数;查表求ASCII码 PUSH A;保存出口参数 INC SP;指向返回地址 INC SP RET;返回主程序 DB 0,1,;ASCII码表,PCL,PCH,01,4-7 算术运算程序4-7-1 多字节加减运算程序,1.多字节加法子程序,Z=X+YADDS:CLR CLOOP:MOV A,R0 ADDC A,R1;加一
21、字节,习题1 编写十进制多字节加法子程序,Z=X+Y习题2 编写多字节减法子程序,Z=X-Y,SETB RS0;选寄存器1区MOV R0,A;存和一字节INC R0;修改指针CLR RS0;选寄存器0区INC R0;修改指针INC R1DJNZ R2,LOOP;全部字节加完?RET,MOV R0,A;存和一字节INC R0;修改指针INC R1DJNZ R2,LOOP;全部字节加完?RET,4-7-2 多字节无符号数乘除运算,移位相加计算多字节乘法程序,步骤:1.部分积清零2.从右至左逐位检测乘数:为1则部分积对位加被乘数,否则加03.对位方法:被乘数左移或部分积右移,初值0:0 0 0 Cy
22、 R4R5 右移R6R7 并检测Cy+R2R3 Cy=1,加被乘数;Cy=0则不加 Cy R4R5 得部分积并右移对位 乘积最后右移一次,110 101 110 000+110 11110,例:双字节数相乘:R2R3R6R7R4R5R6R7解:部分积清零,右移并检测乘数的移出位,决定部分积是否加被乘数,然后部分积右移对位。循环16次,循环16次,相减求商,计算多字节除法程序,步骤:,例 R2R3R4R5R6R7R4R5(余数R2R3)解 1.判断R2R3R6R7?保证商不大于16位 2.被除数左移1位,试减除数 3.若够减,执行商加1并保留余数的操作,10111 0101/01110110 0
23、101 0100 0101 1001 0101 1001 0101 1000 0101 011,CyR2R3R4R50 除数和商同时左移1位-R6R7+1 够减商加1,否则商为0 R2R3,循环16次,1.对齐左端,用被除数高位试减除数2.若够减商上1,不够减商上0且恢复余数3.余数左移或除数右移对位4.循环重复前3步,直至取够相应位数的商,4-7-3 代码转换程序(一)十六进制数转换为ASCII码,(二)ASCII码转换为十六进制数,09的ASCII码:3039H,AF的ASCII码:4146H,HASC:CJNE A,#0AH,NAHEX:CLR C N:JNC N1SUBBA,#30H
24、ADD A,#30HCJNEA,#0AH,N SJMPSEN:JC N1 N1:ADD A,#37HSJMP AE SE:RETN1:SUBB A,#11HCJNE A,#06H,N2N2:JNCERRADDA,#0AHSJMP AEERR:MOVA,#0FFHAE:RET,(三)BCD码与二进制数之间的转换 有乘法和除法两种转换方式,1BCD码转换为二进制数 D=dn-110n-1+dn-210n-2+d1101+d0100=(dn-110+dn-2)10+dn-3)10+d1)10+d0“整数十翻二”:从最高位开始,按二进制运算法则循环“乘十加次低位”:B=B10+bi,2二进制数转换为B
25、CD码B=bn-12n-1+bn-22n-2+b121+b020=(bn-12+bn-2)2+bn-3)2+b1)+b0,乘法转换式:“整数二翻十”:从最高位开始,按十进制运算法则,循环进行“乘 2 加次低位”:D=D2+di,除法转换式:bn-12n-1+bn-22n-2+b0=dm-110m-1+dm-210m-2+d0两边同时除基数,两边的整数或小数应该分别相等除基数,取出1位余数,得到的商继续除基数取余数。循环“除基取余”操作,得到转换进制的各位系数,上机习题:,1.数据串传送2.多字节加减运算3.统计某班单科考试成绩为优秀和不及格的人数4.数据串排序5.查表求函数值 Y=f(X),编程上机考试要求:1.编写程序,标明必要注释,对程序运行结果进行预分析2.上机调试,检查语法错误并改正3.运行程序(F8单步运行,F9连续运行,用Ctr_C返回)1)程序执行前,先设定初值并记录2)程序执行后,记录运行结果4.分析程序运行结果,检查逻辑错误并改正,