第5-2章循环程序设计.ppt
第六章第六章循环程序设计循环程序设计 设问:设问:1怎样用分支结构构成循环?怎样用分支结构构成循环?2循环指令有哪些?循环指令有哪些?3串处理操作是循环执行的吗?串处理操作是循环执行的吗?4.4.多重循环有什么特点?多重循环有什么特点?5.5.如何实现排序如何实现排序?本章重点本章重点循环的概念循环的概念循环指令循环指令串处理串处理多重循环多重循环6.1循环的概念循环的概念 在汇编语言中,程序的循环可以用在汇编语言中,程序的循环可以用分支转移指令实现,也可以用分支转移指令实现,也可以用8086指指令系统中提供的专门的循环指令,这令系统中提供的专门的循环指令,这样使程序更清晰、简便。样使程序更清晰、简便。除了循环指令之外,还有很多地方用除了循环指令之外,还有很多地方用到了循环的概念。例如串处理,需要到了循环的概念。例如串处理,需要对串中的字符循环地进行操作。对串中的字符循环地进行操作。6.1.1循环结构循环结构循环结构有两种形式。一种是循环结构有两种形式。一种是DOWHILE结构,结构,另一种是另一种是DOUNTIL结构。结构。循环程序循环程序有有三部分:三部分:l l设置循环的初始状态设置循环的初始状态l l循环体循环体l l 循环控制部分循环控制部分6.1.1循环程序例子循环程序例子示例示例6-1在在5行行16列上用写显存方法显列上用写显存方法显示多彩字符串。用循环指令实现。示多彩字符串。用循环指令实现。运行结果:运行结果:设计思路:设计思路:(1)用)用DH存放行号,存放行号,DL存放列号;存放列号;(2)BL存放字符属性,第存放字符属性,第1个字符的属性为个字符的属性为4,红色;其他字符属性,红色;其他字符属性+1改变;改变;(3)字符的位置计算公式:行号)字符的位置计算公式:行号*160+列号;列号;(4)用循环指令)用循环指令LOOP实现将多彩字符串循环实现将多彩字符串循环写入显存。写入显存。程序如下:程序如下:;6-1.asm在在5行行16列上用写显存方法显示多彩字符列上用写显存方法显示多彩字符串。串。datasegmenta1dbHelloworld!a2db0dataendscodesegmentassumecs:code,ds:datastart:movdh,5;行行movdl,16;列列movbl,4;属性属性movax,datamovds,axmovsi,0show_str:movax,0b800h;显存首址显存首址moves,axmovax,160muldh;行号行号*160movdi,ax;起始行位置起始行位置saldl,1movdh,0adddi,dx;+列号列号movcx,a2-a1;字符串长度字符串长度let1:moval,si;循环写字符和属性到显存循环写字符和属性到显存moves:di,almovbyteptres:di+1,blincsiincbladddi,2;写完即显示完写完即显示完looplet1;循环指令循环指令movah,4chint21hcodeendsendstart6.2循环指令循环指令格式:格式:LOOPOPR执行的操作:执行的操作:(CX)=(CX)-1,若,若CX0,跳转跳转到标号到标号OPR处循环执行,处循环执行,CX=0则执行则执行LOOP的下一条指令。的下一条指令。说明:目的操作数说明:目的操作数OPR是标号,该标号处的是标号,该标号处的指令应该在指令应该在LOOP指令之前,以构成循环指令之前,以构成循环。6.2.1LOOP循环指令循环指令例例1求求X=1+2+3+10的累加值。的累加值。MOVAL,0MOVBL,1MOVCX,10SS1:ADDAL,BLINCBLLOOPSS1MOVX,AL6.2.2LOOPZ/LOOPE格式:格式:LOOPZ/LOOPEOPR执行的操作:执行的操作:(CX)=(CX)-1,若,若CX0,并且并且ZF=1则跳转到标号则跳转到标号OPR处循环执行,若处循环执行,若CX=0,或者或者ZF=0则执行则执行LOOP的下一条指的下一条指令。令。说明:结果为说明:结果为0或相等循环。当执行到或相等循环。当执行到LOOPZ/LOOPE时,如果之前的指令结果为时,如果之前的指令结果为0或者相等时继续循环,如果结果不为或者相等时继续循环,如果结果不为0或者或者不相等,提前退出循环,即使计数值不相等,提前退出循环,即使计数值CX还没还没减为减为0。STRINGDB*P*MOVCX,10MOVBX,-1MOVAL,0SS3:INCBXCMPSTRINGBX,*LOOPESS3MOVY,BX例例110个星号字符的个星号字符的STRING串中有一个串中有一个字符不是星号,找出该字符的位置,保存字符不是星号,找出该字符的位置,保存在在Y单元。单元。MOVBX,-1MOVCX,MSS4:INCBXMOVAL,ALPHABXTESTAL,20HLOOPZSS4MOVDL,AL例例2取取出出字字母母串串ALPHA中中的的第第一一个个小小写字母放入写字母放入DL。格式:格式:LOOPNZ/LOOPNEOPR执行的操作:执行的操作:(CX)=(CX)-1,若,若CX0,并且并且ZF=0则跳转到标号则跳转到标号OPR处循环执行,若处循环执行,若CX=0,或者或者ZF=1则执行则执行LOOP的下一条指令。的下一条指令。6.2.3LOOPNZ/LOOPNE说明:结果不为说明:结果不为0或不相等循环。或不相等循环。当执行到当执行到LOOPNZ/LOOPNE时,如果之前的时,如果之前的指令结果不为指令结果不为0或者不相等时继续循环,如果或者不相等时继续循环,如果结果为结果为0或者相等,提前退出循环,即使计数或者相等,提前退出循环,即使计数值值CX还没减为还没减为0。MOVBX,0MOVAH,1SS5:INT21HMOVSYMBOLBX,ALINCBXCMPAL,0DHLOOPNESS5MOVAX,0例例1循循环环输输入入字字符符,并并将将字字符符保保存存在在SYMBOL数组中,当输入回车时结束。数组中,当输入回车时结束。MOVBX,-1MOVCX,MSS6:INCBXCMPSYMBOLBX,ALOOPNESS6ORSYMBOLBX,20H例例2在在长长度度为为M的的字字符符串串SYMBOL中中查查找大写字母找大写字母A,找到后将其变为小写。找到后将其变为小写。练习:练习:1写出计算写出计算Y=5!的程序段。的程序段。2写写程程序序段段。查查找找CATT表表中中的的字字符符”,找找到到后后将将其其保保存存到到SIGN单单元元,其其位置值保存到位置值保存到ADDI单元。单元。3写写程程序序段段。在在长长度度为为N的的字字数数组组VALUE中取出第一个负数保存到中取出第一个负数保存到AX中。中。6.3串处理串处理在汇编语言中,可将连续的在汇编语言中,可将连续的n个存储单个存储单元称为串、表、数组等。元称为串、表、数组等。对于这种数据结构的操作称为串处理。对于这种数据结构的操作称为串处理。对串进行操作,需要几个参数,如串对串进行操作,需要几个参数,如串的长度、串的起始单元地址等;而且的长度、串的起始单元地址等;而且串操作大都是循环执行的,循环如何串操作大都是循环执行的,循环如何控制、串的存取方式等都不同于其它控制、串的存取方式等都不同于其它数据操作。数据操作。6.3.1串的概念串的概念6.3.2串处理例子串处理例子设计思路:设计思路:(1)分别定义数据段和附加段;)分别定义数据段和附加段;(2)用)用SI保存源串保存源串STRG1的偏移地址,的偏移地址,DI保存目的串保存目的串STRG2的偏移地址,传送个数的偏移地址,传送个数由由CX指出;指出;(3)用)用CLD指令将方向标志指令将方向标志DF清清0,以便,以便从低地址单元开始取数,依次地址增加,从低地址单元开始取数,依次地址增加,取下一数;取下一数;(4)用)用REPMOVSB指令实现串传送。指令实现串传送。示例示例6-2将数据段中的字符串将数据段中的字符串STRG1传送到传送到附加段的附加段的STRG2中。中。程序如下:程序如下:;6-2.asm串传送串传送datasegmentstrg1db1234567890dataendsextrasegmentstrg2db10dup(?)extraendscodesegmentassumecs:code,ds:data,es:extrastart:movax,datamovds,axmovax,extramoves,axleasi,strg1leadi,strg2cld;方向标志清方向标志清0movcx,10repmovsb;以字节形式重复传送以字节形式重复传送CX次次movah,4chint21hcodeendsendstart运行结果:运行结果:要观察运行结果,采用要观察运行结果,采用DEBUG执行执行6-2.exe。在。在DEBUG下,用下,用U命令查看,找到断点命令查看,找到断点0018,用,用G0018执行,再用执行,再用DES:0命令查看传送结果。命令查看传送结果。此时,数据段的段地址为此时,数据段的段地址为0B45H,而附加而附加段的段地址为段的段地址为0B46H。查看的结果在附查看的结果在附加段中。加段中。思考:如果采用循环指令实现串传送,思考:如果采用循环指令实现串传送,程序如何改写?程序如何改写?6.3.3串处理指令串处理指令8086汇编语言指令系统中提供了汇编语言指令系统中提供了5种串处理指令。种串处理指令。分别是:分别是:MOVS(movestring)串传送串传送CMPS(comparestring)串比较串比较SCAS(scanstring)串扫描串扫描LODS(loadstring)串获取串获取STOS(storestring)串存入串存入上述串指令应该和重复前缀上述串指令应该和重复前缀REP、REPZ/REPE、REPNZ/REPNE结合结合.例例比较两个字串比较两个字串BUNCH1和和BUNCH2是否相同,相是否相同,相同打印同打印Y,不相同打印不相同打印N。示示例例6-3 比比较较两两个个字字串串BUNCH1和和BUNCH2是是否否相相同同,相相同同打打印印Y,不相同打印不相同打印N。程序如下:程序如下:;6-3.asm比较两个字串比较两个字串BUNCH1和和BUNCH2datasegmentbunch1dbstudentbunch2dbstudEntdataendscodesegmentassumecs:code,ds:data,es:datastart:movax,datamovds,axmoves,axleasi,bunch1leadi,bunch2cldmovcx,7repecmpsbjzlet1;相等转相等转LET1movdl,N;不相等,显示不相等,显示Njmpprintlet1:movdl,Y;相等,显示相等,显示Yprint:movah,2hint21hmovah,4chint21hcodeendsendstart6.3.4串与循环串与循环归纳循环结构的几种形式:归纳循环结构的几种形式:(1)用条件转移指令实现循环)用条件转移指令实现循环(2)循环指令)循环指令LOOP/LOOPE/LOOPNE(3)重复前缀重复前缀REP/REPE/REPNE在实际编程中,采用哪种指令实现循环,在实际编程中,采用哪种指令实现循环,要从循环执行的条件和退出循环的要求等要从循环执行的条件和退出循环的要求等方面综合考虑。下面通过几个例子作具体方面综合考虑。下面通过几个例子作具体分析。分析。例例1将将ALPHA数组送入数组送入100个个a。(1)用条件转移指令实现循环用条件转移指令实现循环MOVCX,100MOVSI,0SS0:MOVALPHASI,aINCSIDECCXJNZSS0(2)用)用LOOP指令实现循环指令实现循环MOVCX,100MOVSI,0SS0:MOVALPHASI,aINCSILOOPSS0(3)用串处理用串处理REP前缀实现循环前缀实现循环MOVCX,100MOVDI,OFFSETALPHAMOVAL,aREPSTOSB分析:由于问题简单,只是做赋值操作,且循环分析:由于问题简单,只是做赋值操作,且循环次数已知,所以可以用这三种方法实现。次数已知,所以可以用这三种方法实现。6.4多重循环多重循环1.内循环和外循环的控制内循环和外循环的控制双重循环需要两个循环控制变量双重循环需要两个循环控制变量I,J。多重循环嵌套时,不允许内外循环交叉。多重循环嵌套时,不允许内外循环交叉。6.4.1多重循环结构多重循环结构2内循环和外循环的跳转内循环和外循环的跳转在多重循环程序编写过程中,要注意循环体内条件转在多重循环程序编写过程中,要注意循环体内条件转移指令的转移方向。一般来说,可以从内循环跳入外移指令的转移方向。一般来说,可以从内循环跳入外循环,或者跳出外循环;不允许从外循环跳入内循环循环,或者跳出外循环;不允许从外循环跳入内循环或者直接从循环外跳入循环内。或者直接从循环外跳入循环内。6.4.2排序程序排序程序双重循环程序的典型应用是排序。排序双重循环程序的典型应用是排序。排序采用冒泡算法。采用冒泡算法。冒泡算法的主要思想是从第一个元素开冒泡算法的主要思想是从第一个元素开始,依次对两个相邻的元素进行比较,如果始,依次对两个相邻的元素进行比较,如果第一个元素比第二个大,则两数交换位置,第一个元素比第二个大,则两数交换位置,第一遍第一遍N-1次比较之后,最大的数排在最后;次比较之后,最大的数排在最后;再做第二遍再做第二遍N-2次比较,比较出第二大的数次比较,比较出第二大的数;以此类推,最多进行;以此类推,最多进行N-1遍比较,所遍比较,所有的数按从小到大升序排序。有的数按从小到大升序排序。设计思路:设计思路:(1)用两条)用两条LOOP指令实现双重循环时,对指令实现双重循环时,对CX寄存器有冲突。采用寄存器有冲突。采用PUSHCX指令将外指令将外循环的循环的CX值入栈保存,内循环的值入栈保存,内循环的LOOP结束结束后,再将外循环的后,再将外循环的CX恢复;恢复;(2)用相对寄存器寻址取出两数进行比较。)用相对寄存器寻址取出两数进行比较。示例示例6-5将字数组将字数组PART按升序排序。按升序排序。程序如下:程序如下:;6-5.asm将字数组将字数组part按升序排序。按升序排序。datasegmentpartdw15,32,6,-27,8signdw?dataendscodesegmentassumecs:code,ds:datastart:movax,datamovds,axmovcx,sign-part;数组长度数组长度shrcx,1;元素个数元素个数deccxloop1:pushcx;保存外循环次保存外循环次数数movbx,0loop2:movax,partbxcmpax,partbx+2jlenext;升序升序xchgax,partbx+2;交换交换movpartbx,axnext:addbx,2looploop2popcx;恢复外循环次恢复外循环次数数looploop1movah,4chint21hcodeendsendstart练习:练习:数组数组TABLE中存放中存放8个小个小写字母写字母computer。编程序,将它编程序,将它们按降序排序。们按降序排序。6.5循环程序举例循环程序举例 如如X=5488114433225634H,Y=3499754783645231H,Z=8921868BB686A865H设计思路:设计思路:(1)在数据段中定义两个多字节变量,低字在数据段中定义两个多字节变量,低字节单元存放低位,高字节单元存放高位;节单元存放低位,高字节单元存放高位;(2)字节的个数字节的个数N采用采用EQU赋值伪指令计算赋值伪指令计算获得;获得;(3)多字节相加用带进位加指令多字节相加用带进位加指令ADC;示例示例6-6编程序实现两个多字节数相加运算。编程序实现两个多字节数相加运算。Z=X+Y程序如下:程序如下:;program6-6.asm两个多字节数相加运算两个多字节数相加运算datasegmentxdb34h,56h,22h,33h,44h,11h,88h,54hydb31h,52h,64h,83h,47h,75h,99h,34hnequ$-y;n,字节个数字节个数zdbndup(?)dataendscodesegmentassumecs:code,ds:datastart:movax,datamovds,axmovcx,nmovbx,0clc;将进位标志将进位标志CF清清0let1:moval,xbx;从低位开始从低位开始adcal,ybxmovzbx,alincbxlooplet1movah,4chint21hcodeendsendstart运行结果:运行结果:可以看出,从可以看出,从0号号7号前号前8个字节单元是个字节单元是X,8号号F号号8个单元是个单元是Y,10H号号17H号单元号单元中为相加的结果中为相加的结果Z。6.6实例六实例六循环之循环循环之循环 由于循环指令和转移指令都会改变程序的走向,由于循环指令和转移指令都会改变程序的走向,如果程序有编写思路错误,则不容易找到出如果程序有编写思路错误,则不容易找到出错原因。最简便的方法是直接用错原因。最简便的方法是直接用DEBUG工工具和记事本打开源程序,边调试边修改。具和记事本打开源程序,边调试边修改。6.6.1循环的执行循环的执行(1)把程序调入)把程序调入DEBUG,用,用U命令反汇编,命令反汇编,显示出机器指令和对应的汇编指令显示出机器指令和对应的汇编指令(2)用)用G命令先执行到断点处,再用命令先执行到断点处,再用DDS:0命令查看数据段情况命令查看数据段情况(3)再用单步调试)再用单步调试T命令单步执行,并观察结命令单步执行,并观察结果果(4)打开两个窗口)打开两个窗口(5)执行)执行LOOP指令指令(6)查看结果)查看结果6.6.2实验示例实验示例设计思路:设计思路:(1)外外循循环环控控制制行行数数,内内循循环环控控制制列列数数并并完完成最大值判断;成最大值判断;(2)内内外外循循环环都都用用LOOP指指令令,用用堆堆栈栈保保存存外外循循环环计计数数值值CX,从从外外循循环环进进入入内内循循环环时时要恢复内循环的计数值要恢复内循环的计数值CX;(3)用用已已存存入入一一维维矩矩阵阵MAX的的数数据据与与A矩矩阵阵的的数数据据做做比比较较,较较大大的的数数放放入入MAX后后再再与与其其它数继续比较。它数继续比较。示示例例6-10查查找找34矩矩阵阵A每每行行中中的的最最大大值值,并放入并放入MAX矩阵。矩阵。;6-10.asmdatasegmentadb2,-4,-5,10db3,6,-7,-12db14,-5,9,-3mdw3;3行行ndw4;4列列maxdb3dup(0)dataendscodesegmentassumecs:code,ds:datastart:movax,datamovds,axmovcx,m;共找共找3次次movbx,0movsi,0程序如下:程序如下:rept2:pushcxmovcx,nrept1:moval,abx;找每行最大值找每行最大值cmpal,maxsijlelet2movmaxsi,al;最大值在最大值在maxlet2:incbxlooprept1incsipopcxlooprept2 movah,4ch int21hcodeendsendstart6.6.3实验任务实验任务实验目的:实验目的:通通过过分分析析和和运运行行示示例例程程序序,掌掌握握循循环环程程序序设设计计思思路路和和技技巧巧。根根据据循循环环程程序序设设计计方方法法,尝尝试试设设计计出出各各种种风格的循环程序。风格的循环程序。实验内容:实验内容:参考示例参考示例6-10,完成下列实验内容:,完成下列实验内容:(1)分分别别统统计计3个个班班级级中中某某科科成成绩绩优优秀秀的的人人数数和和不不及格的人数。及格的人数。提提示示:可可以以看看成成3n二二维维数数组组。分分别别用用MAX和和MIN存放存放90分以上和分以上和60分以下的人数。(分以下的人数。(6-11.asm)(2)将将上上述述题题目目改改为为用用两两个个数数组组分分别别存存放放每每班班优优秀的成绩和不及格的成绩。秀的成绩和不及格的成绩。(3)分别对两组成绩按降序排序。分别对两组成绩按降序排序。实验要求:实验要求:(1)3个题目可任选个题目可任选2个个(2)实验内容用截图形式记录实验结果实验内容用截图形式记录实验结果(3)写出实验结果分析写出实验结果分析实验拓展:实验拓展:(1)自自己己设设计计一一个个双双重重循循环环的的题题目目并并编编程程实现。实现。(2)分析例分析例6-8,如果改为在数组中查找,如果改为在数组中查找某元素,然后在其后插入一个数据,程序怎某元素,然后在其后插入一个数据,程序怎么设计?么设计?习题六