第五章程序设计方法和上机调试5.1程序设计方法5.2汇编语言上机调试过程编写汇编语言程序步骤分析实际问题,抽象描述问题的模型确定解决模型的算法按算法画出程序流程图按流程图编写程序上机调试,运行程序5.1程序设计方法判断程序质量的标准程序的正确性程序的可读性程序的执行时间程序所占内存大小执行框判别框开始结束框连接点指向线用流程图表示算法直观形象,比较清楚地显示出各个框之间的逻辑关系。常用的还有N-S结构化流程图。程序编制人员都应当掌握传统流程图,会看会画。流程图的组成顺序程序结构是一种最简单的程序结构。在流程图中,处理框一个接一个执行,既无分支,也无循环和转移。是一种简单的程序结构。S1S2S3一、顺序结构例1:内存中TABLE开始存放0~9的平方值,通过人机对话,当任给定一个数X(0~9),查表得X的平方值,放在AL中。DATASEGMENTTABLEDB0,1,4,9,…81BUFDB‘Pleaseinputonenumber(0~9):’,0DH,0AH,‘$’DATAENDSSTACKSEGMENTSTACK‘STACK’DB50DUP(?)TOPLABELWORDSTACKENDSCODESEGMENTMAINPROCFARASSUMECS:CODE,DS:DATA,SS:STACKSTART:MOVAX,DATAMOVDS,AXMOVAX,STACKMOVSS,AXMOVSP,OFFSETTOPMOVBX,OFFSETTABLENEXT:MOVDX,OFFSETBUFMOVAH,9;输出提示INT21HMOVAH,1;键入一个数INT21HMOVAH,0ANDAL,0FHADDBX,AXMOVAL,[BX]MOVAH,4CHINT21HRETMAINENDPCODEENDSENDSTART▲补充:有关字符、数码转换的处理1.计算机处理字符时,常用的字符编码是ASCII码。2.数字和字母的ASCII码是一个有序序列数字0~9:30H~39H大写字母A~Z:41H~5AH小写字母a~z:61H~7AH3.计算机处理信息时,其对象都是二进制数。外设(显示器、打印机、键盘等)用ASCII码与CPU进行信息传送。例如:1)在键盘上按下某一字符键(如’9’),键盘接口向键盘缓冲区送去的是该字符的ASCII码(如39H),不是送数字09H。2)在文本方式下,要在显示器上显示某一字符(如’A’),须将该字符的ASCII码(如41H)送显示缓冲区,不是送数字0AH。▲计算机要利用显示器、键盘等外设时,须据程序设计的需要进行有关转换。例将CPU运算的结果通过显示器显示时,如二进制数“A9”需将结果转换成其对应的ASCII码才能进行显示。显示缓冲区存放的内容(字符的ASCII码)CPU运算后所得的二进制数10101001十六进制形式显示41h,39h显示’A9’十进制形式显示31h,36h,39h显示’169’(无符号数)2Dh,38h,37h显示’-87’(带符号数)二进制形式显示31h,30h,31h,30h,31h,30h,30h,31h显示’10101001’例CPU要处理从键盘输入的某一数据,如键入“1234”需将该数据串进行转换后才能应用。CPU处理时从键盘输入’1234’,缓冲区存放31H,32H,33H,34H看作十六进制数输入1234H看作十进制数输入04D2H例将BX寄存器中的内容以十六进制形式显示出来。▲BX是一个16位寄存器二进制1010100100111110▲用十六进制显示时,每4位用一个字符显示,共4个其中0000→’0’30H,1010→’A’41H0001→’1’31H,1011→’B’42H、、、、1001→’9’39H,1111→’F’46H?十六进制A93E屏幕上的显示‘A’‘9’‘3’‘E’对应的ASCII41H39H33H45H算法:取出要显示的某4位,转换为对应的ASCII码,再调用DOS系统功能进行显示。1)对于0000~1001(0~9),先扩展成一个字节,高4位清0,加上30H后,即可得字符’0’~’9’对应的ASCII码。00000001B+30H=31H00001001B+30H=39H0001B‘1’1001B‘9’2)对于1010~1111(A~F),先扩展成一个字节,高4位清0,加上30H后,还要再加上07H,才能得到’A’~’F’对应的ASCII码00001010B+30H+07H=41H00001111B+30H+07H=46H1010B‘A’1111B‘F’codeSEGMENTASSUMECS:codestart:MOVCH,4;字符个数MOVCL,4;循环移位次数next:ROLBX,CL;取显示位的值MOVDL,BL;保存在DL中ANDDL,0FH;清除高4位ADDDL,30H;转变为数字的ASCIICMPDL,39H;大于39H,则应转变JLEprint;为字母A~F的ASCIIADDDL,07Hprint:MOVAH,2H;显示DL中的字符INT21HDECCH;显示结束?JNZnextMOVAH,4CH;返回DOSINT21HcodeENDSENDstart显示字符个数CH=4循环移位次数CL=4BX循环左移4位,将要显示的值移至低4位,保存在DL中清DL的高4位,只保留要显示位的值DL←DL+30H完成数值0~9的ASCII码转换YNDL←DL+07H完成数值A~F的ASCII码转换用02功能显示DL中的字符YN返回DOSDL超出39H?CH←CH-1结束?开始1、分支:分支程序结构要求程序在运行过程中需要根据不同的情况或条件作出判断,并转向相应的处理程序。分支是通过条件转移指令实现的。1(X>0)0(X=0)-1(X<0)Y=例2:根据BUFFER中的数(X)对符号函数BX(Y)赋值。二、分支结构程序设计-11XY(AX)=0?(AX)<0?0FFH→BX0→BX1→BXYJENJNS(AX)=0(AX)>0ZEROPLUSX→AX并将AX的特征反映到FLAGNY例3:在以BUF为首地址的内存,存放着一个长度为N(N256)的字符串,编程统计其中数字,字母和其它字符的个数,统计数存放在串后三个单元中。初始化取一字符送AL(AL)≥30H(AL)39H(AL)≥41H(AL)5AHDH+1DL+1(CX)=0修改BX及(CX)-1NNNNNYYYYYADH送内存ADL送内存AL=N-DH-DLAL送内存RET初始化:N送CX;0送DX;0送BX;BX为串偏移量,MOVAL,BUF[BX]‘0’—‘9’30H—39H‘A’—’Z’41H—5AH先介绍第二种DOS返回方法:采用下面的程序框架codeSEGMENTASSUMECS:codemainPROCFAR;使RET为远返回start:PUSHDS;入栈保存地址(DS的值=CS的值)MOVAX,0;程序段前缀的首地址(IP)=0PUSHAX、、;程序主体部分、、RET;取程序段前缀首地址mainENDPcodeENDSENDstartDATASEGMENTBUFDBNDB01H,38H,…76HNUMDB3DUP(?)DATAENDSCODESEGMENTMAINPROCFARASSUMECS:CODE,DS:DATASTART:PUSHDSSUBAX,AXPUSHAXMOVAX,DATAMOVDS,AXMOVCH,NMOVBX,1MOVDX,0LP:MOVAH,BUF[BX]CMPAH,30HJLNEXT;小于‘0’转CMPAH,39HJGABC;大于‘9’转INCDHJMPNEXTABC:CMPAH,41HJLNEXTCMPAH,5AHJGNEXTINCDLNEXT:INCBXDECCHJNZLPMOVBUF[BX],DHMOVBUF[BX+1],DLMOVAH,NSUBAH,DHSUBAH,DLMOVBUF[BX+2],AHRETMAINENDPCODEENDSENDSTART2、多分支有的分支结构为多分支,可依次测试条件是否满足,若满足条件则转入相应分支入口,若不满足继续向下测试,直到全部测试完。简单,直观,速度慢。例:有8个加工子程序,入口地址分别为P1,P2,…P8。编程实现检测键盘输入命令,使系统分别转向8个加工子程序。MOVAH,1INT21H;1号功能调用,键盘输入CMPAL,‘1’JEP1;键值为1,转P1CMPAL,‘2’JEP2;键值为2,转P2:CMPAL,‘8’JEP8;键值为8,转P8JMPST;非法键,转停机P1:…;1号键加工子程序P2:…;2号键加工子程序P8:…;8号键加工子程序ST:HLT局限性?——利用跳转表实现多分支,可克服该方法的缺点。3、跳转表实现多分支利用跳转表实现多分支,可以直接找到相应入口,利用该法需建立一个跳转表,表中含每个分支的入口地址。(1)根据表内地址分支跳转表中存放了每个分支程序的入口地址,只要找到表地址,再将其内容取出,即可得到每个分支程序的入口地址。表地址=跳转表首址+偏移地址教材P173例5-4输入键值开始表首地址BX求偏移量计算地址散转ANDAL,0FHADDAL,ALADDBX,AXJMPWORDPTR[BX]跳转表在内存中的存放方法P0LP0HP1LP1H.........BASE+0BASE+2P0P1MOVBX,OFFSETBASE跳转表中存放着转移指令,查表后程序执行转移指令将转到相应的子程序去。教材P174例5-5P1LP1HP2LP2HBASE.........P1P2JMPJMPMOVAH,1;键入到ALINT21HANDAL,0FHMOVAH,0MOVBL,ALADDAL,ALADDAL,BL;偏移量=键值*3MOVBX,OFFSETBASEADDBX,AX;得转移地址JMPBX;转入转移指令(2)根据表内指令分支转移指令跳转表(3)根据关键字分支P1LP1HP2LP2HBASE.........P1P23132输入关键字开始首地址送BX与关键字比较指针加3转移关键字=0相等YYNN关键字跳转表分支流程图跳转表中存放关键字及相应分支地址。三、循环程序设计循环结束判断:每一次循环要有二个出口。根据循环工作调整的情况,判断是否满足结束条件。若满足结束条件,退出循环;若不满足结束条件,继续循环。循环体:重复执行的一段程序。循环工作部分:循环程序的核心。循环工作调整:重复执行的环境调整。循环初始化:循环程序工作单元的初始化赋值。N循环结束判断结束循环体循环工作部分循环工作调整循环初始化循环程序可以有两种结构形式:DOWHILE结构、DOUNTIL结构循环结构循环初始设置循环体循环条件判断?YNYN循环初始设置循环体循环条件判断?当型循环(当条件成立进入循环)直到型循环(直到条件成立退出循环)循环程序组成部分:1、循环初始化2、循环体3、循环修改4、循环控制循环程序设计举例例设计一个程序,完成从1连加到100(即1+2+…+99+100)的操作,结果保存在数据段的SUM单元。分析:这样的问题如果采用顺序程序设计至少要一百条指令,并且程序的结构性和可读性差,而采用循环程序设计就会简洁明了,结果显示可考虑采用过程调用方式,程序清单如下:DATASEGMENTSUMDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AX;数据段寄存器赋初值;循环初始化SUBAX,AX;工作寄存器清零MOVCX,100;计数器赋初值CLC;清除进位标志LP:INCAX;循环体ADCSUM,AXDECCX;循环修改JNZLP;循环控制;********;插入显示程序的地方(预留位置)HLTCODEENDSENDSTART注意:①本程序段采用了第三种退出方式,程序运行结束将由于执行HLT指令而进入停机状态,当键入Ctrl+Break组合键(键盘中断)后,返回DOS现场。②用DEBUG跟踪,会发现(SUM)=13BAH。四、子程序主程序CAL