第5章程序控制结构及其程序设计优秀PPT.ppt
第第5章程序控制结构章程序控制结构及其程序设计及其程序设计现在学习的是第1页,共121页5.1 汇编语言程序设计概述汇编语言程序设计概述 5.1.1 汇编语言程序设计的基本步骤 编制汇编语言程序的基本步骤如下:(1)分析问题,抽象出描述问题的数学模型。遇到一个题目,特别是一个较为复杂的题目,先要对其进行全面的分析,看它给出了什么条件,有什么特点,找出规律,归纳出数学模型。当然,也可能有些问题不用写出数学模型或写不出数学模型。现在学习的是第2页,共121页 (2)确定算法。有了数学模型,或虽然没有数学模型但已把题目分析清楚了,就选择一个合适的算法和适当的数据结构。如果没有可供选用的现成的算法和结构,就需要针对具体问题设计一个算法或结构。(3)绘制流程图。流程图就是用图形的方式把解决问题的算法直观地描述出来。对于一个比较复杂的问题,画出流程图,这有助于对问题的理解以及有助于编写出正确的程序。当然,如果算法比较简单,也可不画流程图。现在学习的是第3页,共121页 (4)分配存储空间和工作单元。用汇编语言编写程序时,需要给程序中的变量指定内存单元地址或指定寄存器。(5)编写程序。要把题目中需要处理的数据合理地根据(2)、(3)、(4)步的工作,选用适合的指令,并按一定的语法规则编写相应的程序。(6)静态检查。静态检查就是用人工的方式检查程序是否有错误,包括算法错误和语法错误等,如果有错误,及时改正过来。处理得好,静态检查能够发现和改正程序中的大部分错误。现在学习的是第4页,共121页 (7)上机调试运行。任何程序必须经过调试,才能检查出解题目的是否正确以及程序是否符合设计思想。在调试程序的过程中,应该善于利用机器提供的调试工具和有效的其他工具软件来进行工作,经过反复的“运行发现错误改正错误运行”,才能得到正确的程序。这一点对初学者特别重要,它将给汇编语言编程提供很大的帮助。程序的编写和调试运行是学好汇编语言的重要手段。只有多编写程序和多调试运行程序,才能有效地提高编写和阅读程序的能力。现在学习的是第5页,共121页 5.1.2 程序流程图 表示一个算法,可以用不同的方法。常用的有自然语言、传统流程图和结构化流程图等。1.用自然语言表示算法 很多算法是用自然语言表示的,自然语言是指人们日常使用的语言。用自然语言表示算法通俗易懂,但文字冗长,容易出现“歧义性”。自然语言表示的含义往往不大严格,要根据上下文才能判断其正确的含义。假如有这样一句话:“王先生对刘先生说孩子考上了大学。”现在学习的是第6页,共121页 先生的孩子考上大学呢,还是刘先生的孩子考上大学呢?光从这句话本身难以判断。此外,用自然语言描述包含分支和循环的算法很不方便。因此,除了很简单的问题以外,一般程序设计不用自然语言描述算法。2.流程图的组成 流程图是用一些图框表示各种操作。用图形表示算法,直观形象,易于理解。美国国家标准化协会ANSI(American National Standard Institute)规定了一些常用的流程图图元(见图5.1),已被世界各国程序工作者普遍采用。现在学习的是第7页,共121页 借助于流程图可以清晰地把程序思路表达出来,有助于编写正确的程序。流程图对于程序设计人员,特别是初学者是一种非常有用的工具。流程图一般由6种成分组成,如图5.1所示。现在学习的是第8页,共121页图5.1 流程图的组成成分图现在学习的是第9页,共121页 1)执行框(矩形框)图5.1中的方框,其作用是表示一段程序或一个模块的功能,对于结构化程序,一个执行框只有一个入口和一个出口。2)判别框(菱形框)图5.1中的菱形框,其作用是对一个给定的条件进行判断,根据给定的条件是否成立来决定如何执行其后的操作。它有一个入口,两个出口,如图5.2所示。现在学习的是第10页,共121页图5.2 流程图的绘制示意 现在学习的是第11页,共121页 3)开始框和终止框 图5.1中的圆头方框表示程序的起始和终止。4)指向线 指向线表示程序执行的顺序。5)连接点 图5.1中小圆圈是连接点,用于将画在不同地方的流程线连接起来。如图5.2中有两个以为标志的连接点,它表示这两个点是互相连接在一起的。实际上它们是同一个点,只是当在纸张上画不下时才分开来画。用连接点,可以避免流程线的交叉或过长,使流程图清晰。现在学习的是第12页,共121页 流程图是表示算法的较好工具。一个流程图包括以下几部分:(1)表示相应操作的框;(2)带箭头的流程线;(3)框内外必要的文字说明。绘制流程线不要忘记画箭头,因为它是反映流程执行的先后次序的,如不画出箭头就难以判定各框的执行次序了。现在学习的是第13页,共121页 用流程图表示算法直观、形象,能比较清楚地显示出各个框之间的逻辑关系。前一时期国内外计算机书刊都广泛使用这种流程图表示算法,但是,这种流程图占用篇幅较多,尤其当算法比较复杂时,画流程图既费时又不方便,在结构化程序设计方法推广之后,许多书刊已用N-S结构化流程图代替这种传统的流程图。但是每一个程序编制人员都应当熟练掌握传统流程图,做到会看会画。现在学习的是第14页,共121页 3.三种基本结构和改进的流程图 1)传统流程图的弊端 传统的流程图用流程线指出各框的执行顺序,对流程线的使用没有严格限制。因此,使用者可以不受限制地使流程随意地转来转去,使流程图变得毫无规律。阅读者要花很大精力去追踪流程,使人难以理解算法的逻辑。这种情况如图5.3所示。这种如同乱麻一样的算法称为BS型算法,意为就像一碗面条(A Bowl of Spaghetti),乱无头绪。现在学习的是第15页,共121页图5.3 杂乱流程示意现在学习的是第16页,共121页图5.4 顺序结构图 现在学习的是第17页,共121页 为了提高算法的质量,使算法的设计和阅读更方便,必须限制滥用箭头,即不允许无规律地使流程随意转向,只能顺序地进行下去。但是,算法上难免会包含一些分支和循环,而不可能全部由一个一个框顺序组成。为了解决这个问题,人们设想,规定出几种基本结构,然后由这些基本结构按一定规律组成一个算法结构(如同用一些基本预制构件来搭成房屋一样),整个算法的结构是由上而下地将各个基本结构顺序排列起来的。如果能做到这一点,算法的质量就能得到保证和提高。现在学习的是第18页,共121页 2)三种基本结构 1966年,BOHRA和JACOPINI提出了以下三种基本结构,用这三种基本结构作为表示一个良好算法的基本单元。(1)顺序结构。如图5.4所示,虚线框内是一个顺序结构。其中A和B两个框是顺序执行的。即在执行完A框所指定的操作后,必然接着执行B框所指定的操作。顺序结构是最简单的一种基本结构。现在学习的是第19页,共121页 (2)选择结构(分支结构)。如图5.5所示,虚线框内是一个选择结构。此结构中必包含一个判断框。根据给定的条件P是否成立而选择执行A框或B框。请注意,无论P条件是否成立,只能执行A框或B框之一,不可能既执行A框又执行B框。无论走哪一条路径,在执行完A或B之后,都经过b点,然后脱离本选择结构。A或B两个框中可以有一个是空的,即不执行任何操作。(3)循环结构(又称重复结构)。循环结构指反复执行某一部分的操作,有当型(WHILE型)循环、直到型(UNTIL型)循环和计数型(FOR-NEXT)循环。现在学习的是第20页,共121页图5.5 选择结构图 现在学习的是第21页,共121页 4.结构化程序设计的特点 三种基本循环结构的共同特点如下:(1)只有一个入口。(2)只有一个出口。尽管一个菱形判断框有两个出口,但由它构成的一个选择结构仍只有一个出口。不要将菱形框的出口和选择结构的出口混淆。(3)各功能框均可执行。结构内的每一部分都有机会被执行到,也就是说,对每一个框而言,都应当有一条从入口到出口的路径通过它。现在学习的是第22页,共121页 (4)结构中无死循环。实践证明,由以上三种基本结构顺序组成的算法结构,可以解决任何复杂的问题。由基本结构所构成的算法属于“结构化”的算法,它不存在无规律的转向,只在本结构内才允许存在分支、向前或向后的跳转。基本结构不一定只限于上面三种,只要具有上述四个特点的都可以作为基本结构。人们可以自己定义基本结构,并由这些基本结构组成结构化程序。现在学习的是第23页,共121页5.2 顺序程序设计顺序程序设计 在顺序程序结构中,完全按顺序逐条执行指令序列,这种情况在程序中大量存在,但仅由顺序结构构成的作为完整的程序则很少见。顺序结构的程序是最简单的程序。现在学习的是第24页,共121页 【例5-1】将两个字节数据相加,并存放到一个结果单元中。DATASEGMENT AD1DB4CH;定义第1个加数 AD2DB25H;定义第2个加数 SUMDB?;定义结果单元 DATAENDS CODESEGMENT现在学习的是第25页,共121页ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV AL,AD1 ;取出第1个加数 ADD AL,AD2;和第2个加数相加 MOV SUM,AL;存放结果 MOV AH,4CH INT 21H;返回DOS CODE ENDS ENDSTART现在学习的是第26页,共121页 【例5-2】将一个字节压缩BCD码转换为两个ASCII码。分析:一个字节的压缩BCD码就是用一个字节的二进制数表示两位十进制数,如十进制数96表示成压缩BCD码就是96H,转换成ASCII码就是把压缩BCD码表示的十进制数的高位和低位分开,并以ASCII码表示,即转换成39H和36H。现在学习的是第27页,共121页DATASEGMENTBCDBUFDB96H;定义1个字节的压缩BCD码ASCBUF DB2DUP(?);定义2个字节的结果单元DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA现在学习的是第28页,共121页START:MOVAX,DATA MOVDS,AX MOV AL,BCDBUF ;取出BCD码 MOVBL,AL;送BL暂存 MOVCL,4 SHRAL,CL ;高4位变成低4位,高4位补0(96H09H)ADDAL,30H ;变成ASCII码(39H)现在学习的是第29页,共121页MOVASCBUF,AL;存储第1个ASCII码ANDBL,0FH;屏蔽掉高4位,只保留低4位(96H06H)ADDBL,30H;变成BCD码(36H)MOVASCBUF+1,BL;存储第2个码MOVAH,4CHINT21HCODE ENDSENDSTART现在学习的是第30页,共121页 【例5-3】利用直接查表法完成将键盘输入的一位10进制数(09)转换成对应的平方值并存放在SQRBUF单元中。分析:09的平方值分别为0、1、4、9、16、25、36、49、64、81。把平方值放在一起形成一个平方值表,根据输入的值和对应平方值所在单元地址之间的关系(表首地址加上输入的值),查出相应的平方值。现在学习的是第31页,共121页DATASEGMENTSQUTABDB0,1,4,9,16,25,36,49,64,81SQUBUFDB?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATA现在学习的是第32页,共121页MOV DS,AXMOV BX,OFFSETSQUTAB ;平方表首地址MOV AH,1INT21H ;由键盘输入个数,得到其ASCII码SUBAL,30H;由ASCII码得到相应的数XLAT;查表MOV SQUBUF,AL ;存储结果现在学习的是第33页,共121页MOVAH,4CHINT21HCODE ENDS END START现在学习的是第34页,共121页5.3 分支程序设计分支程序设计 5.3.1 分支程序的结构形式 分支程序结构可以有两种形式,如图5.6所示。不论哪一种形式,它们的共同特点是:运行方向是向前的,在某一种特定条件下,只能执行多个分支中的一个分支。现在学习的是第35页,共121页图5.6 分支程序的结构形式现在学习的是第36页,共121页 5.3.2 分支程序设计方法 程序的分支一般用条件转移指令来产生,利用条件转移指令不影响条件码的特性,可以连续使用条件转移指令使程序产生多个不同的分支如下例。【例5-5】在附加段中,有一个按从小到大顺序排列的无符号数数组,其首地址存放在DI寄存器中,数组中的第一个单元存放着数组长度,在AX中有一个无符号数,要求在数组中查找(AX)。如找到,则使CF=0,并在SI中给出该元素在数组中的偏移地址;如未找到,则使CF=1。现在学习的是第37页,共121页 上述章节遇到的过多个表格查找的例子,大都使用顺序查找的方法。本例是一个已经排序的数组,可以采用折半查找法以提高查找效率。折半查找法先取有序数组的中间元素与查找值相比较。如相等则查找成功;如查找值大于中间元素,则再取高半部的中间元素与查找值相比较。如查找值小于中间元素,则再取低半部的中间元素与查找值相比较。如此重复直到查找成功或最终未找到该数为止。现在学习的是第38页,共121页 折半查找法的效率高于顺序查找法,对于长度为N的表格,顺序查找法平均要作N2次比较,而折半查找法的平均比较次数为lb N。所以,如果数组长度为100,则顺序查找法平均要作50次比较,而折半查找法平均作7次比较就可以了。在一个长度为N的有序数组R中,查找元素K的折半查找算法可描述如下:现在学习的是第39页,共121页 (1)初始化被查找数组的首尾下标,LOWL,HIGHN。(2)若LOWHIGH,则查找失败,置CF1,退出程序。否则,计算中点:MID(LOW+HIGH)2。(3)K与中点元素RMID比较。若K=RMID则查找成功,程序结束;若KRMID,则转步骤(5)。(4)低半部分查找(Lower),HIGHMID-1,返回步骤(2),继续查找。现在学习的是第40页,共121页 (5)高半部分查找(Higher),LOWMID+1,返回步骤(2),继续查找。图5.7表示了折半查找算法的程序框图。给出的程序首先把查找值与数组的第一个元素和最后一个元素相比较,如果找到该数小于第一个元素或大于最后一个元素则结束查找,否则从SEARCH开始折半查找。SEARCH以前的工作在图5.7中未表示出来。折半查找算法的程序实现如程序清单所示。现在学习的是第41页,共121页图5.7 折半查找算法的程序框图现在学习的是第42页,共121页例5-5折半查找算法程序。DSEGSEGMENTLOW_IDW?HIGH_IDW?DSEGENDSCSEGSEGMENTASSUME CS:CSEG,DS:DSEG,ES:DSEG现在学习的是第43页,共121页B_SRCHPROC NEARPUSH DS PUSH AXMOVAX,DSEGMOVDS,AXMOVES,AXPOPAXCMPAX,ES:DI+2JACHK_LAST现在学习的是第44页,共121页 LEASI,ES:DI+2 JEEXIT STC JMPEXIT CHK_LAST:MOVSI,ES:DI SHLSI,1 ADDSI,DI CMPAX,ES:SI JBSEARCH JEEXIT现在学习的是第45页,共121页 STC JMPEXITSEARCH:MOVLOW_I,1 MOVBX,ES:DI MOVHIGH_I,BX MOVBX,DI MID:MOVCX,LOW_I MOVDX,HIGH_I CMPCX,DX JANO_MATCH现在学习的是第46页,共121页 ADDCX,DX SHRCX,1 MOV SI,CX SHLSI,1COMPARE:CMPAX,ES:BX+SI JEEXIT JAHIGHER DECCX MOVHIGH_I,CX JMPMID现在学习的是第47页,共121页HIGHER:INCCX MOV LOW_I,CX JMPMIDNO_MATCH:STCEXIT:POPDS RET B_SRCH ENDPCSEG ENDS ENDB SRCH现在学习的是第48页,共121页 若数组元素如下:LIST DW 12,11,22,33,44,55,66,77,88,99,111,222,333 如果要查找的数为(AX)=55。数组长度为12,第一次比较的是数组的第六个元素。因5533,所以第三次用高半部折半查找,比较的是第四个元素44。因5544,所以第四次用高半部折半查找,比较的是第五个元素55。这样经过四次比较后,因查找成功而退出程序。现在学习的是第49页,共121页 如果要查找的数为(AX)=57,则第一次比较的仍是第六个元素66。因5733,所以第三次用高半部折半查找,比较的是第四个元素44。因5744,所以第四次用高半部折半查找,比较的是第五个元素55,因 5755,再 用 高 半 部 折 半 查 找 时,因LOWHIGH而以查找失败退出程序。现在学习的是第50页,共121页 可以看出,在这个例子中,同样用CMP指令以及条件转移指令产生两个或多个程序分支。当然,由于多数运算型指令置条件码,所以在条件转移指令之前并不一定要使用CMP或TEST指令,只要保证使用条件转移指令时的条件码符合要求就可以了。以上多个例子都是既有分支结构又包括循环结构,实际上,多数程序都是各种程序结构的组合。而且,循环结构可以看作分支结构的一种特例,它只是多次走一个分支,只在满足循环结束条件时,走另一个分支罢了。现在学习的是第51页,共121页 5.3.3 跳跃表法 分支程序的两种结构形式都可以用上面所述的方法来实现。此外,在实现CASE结构时,还可以使用跳跃表法,使程序能根据不同的条件转移到多个程序分支中去。下面举例说明。【例5-6】试根据AL寄存器中哪一位为1(从低位到高位)就把程序转移到8个不同的程序分支中去。现在学习的是第52页,共121页 下面列出了用变址寻址方式实现跳跃表法的程序,还可以使用寄存器间接和基址变址寻址方式来达到同一目的,这三种方法并无实质的区别,只是其中关键的JMP指令所用的寻址方式不同而已。跳跃表法是一种很有用的分支程序设计方法,应当通过例子掌握要领,灵活使用。用变址寻址方式实现跳跃表法的程序:现在学习的是第53页,共121页DATASEGMENTDATATABDW ROUTINE_1DW ROUTINE_2DW ROUTINE_3DW ROUTINE_4DW ROUTINE_5DW ROUTINE_6DW ROUTINE_7DW ROUTINE_8现在学习的是第54页,共121页 DATA ENDS CODE SEGMENT MAIN PROCFARASSUME CS:CODE,DS:DATASTART:PUSH DS SUBBX,BX PUSH BX MOVBX,DATA MOVDS,BX CMPAL,0 现在学习的是第55页,共121页 JECONT MOV SI,0LP:SHRAL,1 JNBNOT_YET JMPDATATABSI NOT_YET:ADDSI,TYPE DATATAB JMPLPCONT:ROUTINE_1:ROUTINE_2:现在学习的是第56页,共121页RETMAINENDPCODEENDSENDSTART现在学习的是第57页,共121页【例5-7】用间接寻址方式实现跳跃表法的程序:CMPAL,0 JECONTINUE_MAIN_LINE LEABX,DATATABLP:SHRAL,1 JNBNOT_YET JMPWORD PTRBX NOT_YET:ADDBX,TYPE DATATAB JMPLPCONTINUE_MAIN_LINE:现在学习的是第58页,共121页5.4 循环程序设计循环程序设计 5.4.1 循环程序结构 循环程序结构可以总结为两种结构形式,如图5.8所示。一种是DO_WHILE结构形式,另一种是DO_UNTIL结构形式。现在学习的是第59页,共121页图5.8 循环程序的结构形式现在学习的是第60页,共121页 1.DO_WHILE结构 DO_WHILE结构把对循环控制条件的判断放在循环的入口,先判断条件,满足条件就执行循环体,否则就退出循环。2.DO_UNTIL结构 DO_UNTIL结构则先执行循环体,然后再判断控制条件,不满足条件则继续执行循环操作,一旦满足条件则退出循环。现在学习的是第61页,共121页 这两种结构可以根据具体情况选择使用。如果允许循环次数等于0的情况,应选择DO_WHILE结构,否则使用DO_UNTIL结构。不论哪一种结构形式,循环程序都可由如下三部分组成:(1)循环的初始状态。设置循环次数的计数值,为使循环体正常工作而建立的初始状态等。(2)循环体。这是循环工作的主体,由循环的工作部分和修改部分组成。循环的工作部分是为完成程序功能而设计的主要程序段;循环的修改部分则是为保证每一次重复(循环)时,参加执行的信息能发生有规律的变化而建立的程序段。现在学习的是第62页,共121页 (3)循环控制部分。循环控制本来应该属于循环体的一部分,由于它是循环程序设计的关键,所以要对它作专门的讨论。每个循环程序必须选择一个循环控制条件来控制循环的运行和结束,而合理地选择该控制条件就成为循环程序设计的关键问题。现在学习的是第63页,共121页 有时,循环次数是已知的,此时可以用循环次数作为循环的控制条件,LOOP指令使这种循环程序设计能很容易地实现。有时循环次数是已知的,但有可能使用其他特征或条件来使循环提前结束,LOOPZ和LOOPNZ指令又是设计这种循环程序的工具。然而,有时循环次数是未知的,那就需要根据具体情况找出控制循环结束的条件。循环控制条件的选择是很灵活的,有时可供选择的方案不止一种,此时就应分析比较,选择一种效率最高的方案来实现。现在学习的是第64页,共121页 5.4.2 循环程序设计方法 【例5-8】试编制一个程序,把BX寄存器内的二进制数用十六进制数的形式在屏幕上显示出来。根据题意应该把BX的内容从左到右每四位为一组在屏幕上显示出来,每次循环显示一个十六进制数位,计数初值为4。现在学习的是第65页,共121页图5.9 二进制数到十六进制数转换的程序框图现在学习的是第66页,共121页 程序框图如图5.9所示。采用循环移位的方式把所要显示的4位二进制数移到最右面,以便做数字到字符的转换工作。此外,由于数字09的ASCII值为30H39H,而字母AF的ASCII值为41H46H,所以在把4位二进制数加上30H后还需再作一次判断。如果是字符AF,则还应加上7才能显示出正确的十六进制数。以BINIHEX.ASM为文件名建立“二进制到十六进制数转换程序”源文件。现在学习的是第67页,共121页 在程序中没有使用LOOP指令,这是因为循环移位指令要使用CL寄存器,而LOOP指令要使用CX寄存器,为了解决CX寄存器的冲突问题,这里用CH寄存器存放循环计数值,而用DEC及JNZ两条指令完成LOOP指令的功能。这说明使用计数值控制循环结束也可以不用LOOP指令。当然也可以把计数值初始化为0,用每循环一次加1然后比较次数是否达到要求的方法来实现;或者仍用LOOP指令,而用堆栈保存其中的一个信息(例如计数值)来解决CX寄存器的冲突问题等。总之,程序设计是很灵活的,只要算法和指令的使用没有错误,都可以达到目的。二进制数到十六进制数转换程序:现在学习的是第68页,共121页 CODE SEGMENT MAINPROC FAR ASSUME CS:CODESTART:PUSH DS SUB AX,AX PUSH AX MOV CH,4LP:MOV CL,4 ROL BX,CL MOV AL,BL现在学习的是第69页,共121页 AND AL,0FH ADD AL,30H CMP AL,3AH JL PRINTA ADD AL,07HPRINTA:MOV DL,AL MOV AH,2 INT 21H DEC CH现在学习的是第70页,共121页JNZ LP RET MAIN ENDPCODE ENDS ENDSTART现在学习的是第71页,共121页 【例5-9】在ADDR单元中存放着数Y的地址,试编制一程序把Y中1的个数存入COUNT单元中。要测出Y中1的个数就应逐位测试。一个比较简单的办法是可以根据最高有效位是否为1来计数,然后用移位的方法把各位数逐次移到最高位去。现在学习的是第72页,共121页 循环的结束可以用计数值为16来控制,但更好的办法是:结合上述方法可以用测试数是否为0来作为结束条件,这样可以在很多情况下缩短程序的执行时间。此 外,考 虑 到 Y本 身 为 0的 可 能 性,应 该 采 用DO_WHILE的结构形式。根据以上考虑,可以画出图5.10的程序框图并编制“数1的程序”。现在学习的是第73页,共121页图5.10 数1的程序框图现在学习的是第74页,共121页TITLE 数1的程序DATA SEGMENT ADDRDW NUMBER NUMBERDW Y COUNTDW?DATA ENDSCODE SEGMENTMAIN PROC FAR现在学习的是第75页,共121页ASSUME CS:CODE,DS:DATASTART:PUSH DS SUBAX,AX PUSH AX MOVAX,DATA MOVDS,AX MOVCX,0 MOVBX,ADDR MOVAX,BX现在学习的是第76页,共121页REPEAT:CMPAX,0 JZEXIT JNS SHIFT INCCXSHIFT:SHLAX,1 JMPREPEATEXIT:MOV COUNT,CX 现在学习的是第77页,共121页 RET MAIN ENDPCODE ENDS END START ;运行时,Y应赋具体值现在学习的是第78页,共121页 【例5-10】设有数组X和Y,X数组中有X1,X10;Y数组中有Y1,Y10。试编制程序计算 Z1X1+Y1 Z5X5-Y5 Z8X8-Y8 Z2X2+Y2 Z6X6+Y6 Z9X9+Y9 Z3X3-Y3 Z7X7-Y7 Z10X10+Y10 Z4X4-Y4 结果存入Z数组。现在学习的是第79页,共121页 对于这种问题,也可用循环程序结构来完成。已知循环计数值为10,每次循环的操作数是可以顺序取出的,但所作的操作却有所不同,这里有加法和减法两种操作。为了区别每次应该做哪一种操作,可以设立标志位,如标志位为0做加法,为1则做减法。这样,进入循环后只要判别标志位就可确定应该做的操作了。显然,这里要做10次操作就应该设立10个标志位,我们把它放在一个存储单元LOGIC_RULE中,这种存储单元一般称为逻辑尺。本例设定的逻辑尺为 0000000011011100现在学习的是第80页,共121页 从低位开始所设的标志位反映了每次要做的操作顺序,最高的6位没有意义。程序框图如图5.13所示。现在学习的是第81页,共121页图5.13 例5-12的程序框图现在学习的是第82页,共121页TITLE 例5-12程序DATASEGMENTXDWX1,X2,X3,X4,X5,X6,X7,X8,X9,X10YDWY1,Y2,Y3,Y4,Y5,Y6,Y7,Y8,Y9,Y10ZDWZ1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9,Z10LOG_RU DW00DCHDATAENDS CODESEGMENTMAINPROCFAR现在学习的是第83页,共121页ASSUME CS:CODE,DS:DATA START:PUSH DS SUBAX,AX PUSH AX MOV AX,DATA MOV DS,AX MOV BX,0 MOV CX,10 MOVDX,LOG_RU现在学习的是第84页,共121页NEXT:MOVAX,XBX SHRDX,1 JCSUBT ADDAX,YBXJMPSHORTRESULTSUBT:SUBAX,YBXRESULT:MOVZBX,AXADDBX,2LOOPNEXTRETMAINENDPCODEENDS END START 现在学习的是第85页,共121页 本例中X1X10,Y1Y10,Z1Z10均需采用实际数值才可运行 这种设置逻辑尺的方法是很常用的。例如,在矩阵运算中,为了跳过操作数为0的计算,经常采用这种方法。又如,把一组数据存入存储器时,如果其中数值为0的元素很多,也可用这种方法设立一个每位表示一个下标的逻辑尺(这样的逻辑尺可能占有几个字,由数组的长度确定),0元素就可不占用存储单元了。现在学习的是第86页,共121页 在例5-12中,每个标志只占一位,如果要表示的特征数更多,则每个标志可占用几位,而在处理方法上是完全相同的。设立标志位的方法除了如逻辑尺那样可静态地预置外,还可以在程序中动态地修改标志位的值,以达到控制的目的。下例将说明这种方法。现在学习的是第87页,共121页 【例5-11】试编制一程序。从键盘输入一行字符,要求第一个键入的字符必须是空格符。如不是,则退出程序;如是,则开始接收键入的字符并顺序地存放在首地址为BUFFER的缓冲区中(空格符不存入),直到接收到第二个空格符时退出程序。这一程序要求接收的字符从空格符开始又以空格符结束,因此程序中必须区分所接收的字符是否为第一个字符。为此,设立作为标志的存储单元FLAG。一开始将其置为0,接收第一个字符后可将其置1。整个程序的框图如图5.14所示。现在学习的是第88页,共121页图5.14 例5-13的程序框图 现在学习的是第89页,共121页TITLE 例5-11程序DATA1SEGMENTBUFFERDB80 DUP(?)FLAG DB?DATA1ENDSCODESSEGMENTMAIN PROCFARASSUME CS:CODES,DS:DATA1现在学习的是第90页,共121页START:PUSH DS SUBAX,AXPUSH AXMOVAX,DATA1MOVDS,AXLEABX,BUFFERMOVFLAG,0现在学习的是第91页,共121页NEXT:MOVAH,01INT21HTEST FLAG,01HJNZFOLLOWCMPAL,20HJNZEXITMOVFLAG,1 JMPNEXT现在学习的是第92页,共121页FOLLOW:CMPAL,20HJZEXITMOVBX,ALINCBXJMPNEXTEXIT:RET MAINENDP CODESENDSENDSTART现在学习的是第93页,共121页实验内容现在学习的是第94页,共121页DOS功能调用格式:INT 21H 调用参数在AH中.(一)显示单个字符02号调用格式:MOV DL,字符 MOV AH,02H INT 21H现在学习的是第95页,共121页(二)字符串显示-9号调用格式:MOV DX,OFFSET STRING MOV AH,09H INT 21H功能:在CRT 上显示以$结束的字符串。入口:DS:DX指向字符串首址。例:STR:DB HELLO$MOV AX,SEG STRMOV DS,AXMOV DX,OFFSET STRMOV AH,09HINT 21H现在学习的是第96页,共121页(三)单个字符输入-01号调用格式:MOV AH,01HINT 21H出口参数:AL中为键盘输入的单个字符ASCII同时在CRT上显示.例:MOV AH,01HINT 21H ;等待键入MOV CHAR,AL现在学习的是第97页,共121页(四)字符串输入10号调用格式:MOV DX,OFFSET BUFFER MOV AH,0AH INT 21H功能:从键盘输入字符串到M的缓冲区,以回车结束。入口参数:DS:DX指向缓从区。现在学习的是第98页,共121页实验一现在学习的是第99页,共121页 data segment question db What is your name?,0dh,0ah,$answer db 40,?,40 dup(?)data ends stack segment stack stack sap db 100h dup(?)top equ length sap stack ends 现在学习的是第100页,共121页code segment assume cs:code,ds:data,ss:stack start:mov ax,data mov ds,ax mov ax,stack mov ss,ax mov sp,top 现在学习的是第101页,共121页 mov dx,offset question mov ah,09h int 21h mov dx,offset answer mov ah,0ah int 21h 现在学习的是第102页,共121页 mov dl,0dh mov ah,2 int 21h mov dl,0ah mov ah,2 int 21h现在学习的是第103页,共121页 mov si,offset answer mov ch,0 mov cl,si+1 l1:mov dl,si+2 mov ah,02h int 21h inc si loop l1 现在学习的是第104页,共121页 mov ah,4ch int 21h code ends end start现在学习的是第105页,共121页实验二现在学习的是第106页,共121页data segment buffer db 20h,68h,2fh,8ah,9fh,3dh,0c5h,78h,69h,57hcount equ$-offset buffer data ends stack segment stack stack sap db 100h dup(?)top equ length sap stack ends现在学习的是第107页,共121页 code segment assume cs:code,ds:data,ss:stack start:mov ax,data mov ds,ax mov ax,stack mov ss,ax mov sp,top现在学习的是第108页,共121页 mov cx,count dec cx top1:mov dx,cx mov si,offset buffer top2:mov al,si cmp al,si+1 jle l1 现在学习的是第109页,共121页 xchg al,si+1 mov si,al l1:inc si loop top2 mov si,offset buffer mov cx,dx loop top1 mov cx,count ;display mov si,offset buffer现在学习的是第110页,共121页 l4:mov al,si mov dh,al shr al,1 shr al,1 shr al,1 shr al,1 cmp al,0ah 现在学习的是第111页,共121页 jl l2 add al,07h l2:add al,30h mov dl,al mov ah,2 int 21h and dh,0fh现在学习的是第112页,共121页 cmp dh,0ah mov dl,dh jl l3 add dl,07h l3:add dl,30h mov ah,2 int 21h现在学习的是第113页,共121页 mov dl,0dh mov ah,2 int 21h mov dl,0ah mov ah,2 int 21h inc si现在学习的是第114页,共121页 loop l4 mov ah,4ch int 21h code ends end start现在学习的是第115页,共121页习习 题题 5 5.1 编写程序,从键盘接收一个小写字母,然后找出它的前导字符和后续字符,再按顺序用大写字母显示这三个字符。5.2 将AX寄存器中的16位数分成4组,每组4位,然后把这4组数分别放在AL、BL、CL和DL中。5.3 试编写一程序,要求比较两个字符串STRING1和STRING2所含字符是否相同,若相同则显示MA