世纪高等院校规划教材.pptx

上传人:一*** 文档编号:27522564 上传时间:2022-07-25 格式:PPTX 页数:58 大小:219.90KB
返回 下载 相关 举报
世纪高等院校规划教材.pptx_第1页
第1页 / 共58页
世纪高等院校规划教材.pptx_第2页
第2页 / 共58页
点击查看更多>>
资源描述

《世纪高等院校规划教材.pptx》由会员分享,可在线阅读,更多相关《世纪高等院校规划教材.pptx(58页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、第5章 循环程序设计 本章主要讲解循环程序的基本结构和设计方法。通过本章学习,读者应该掌握以下内容: 循环程序的一般结构形式 循环指令 计数型循环与条件型循环 单重循环程序设计方法 多重循环程序设计方法第1页/共58页5.1 循环程序的一般结构 循环程序按照结构可分为单重循环和多重循环,按照循环控制的方法,可分为计数型循环与条件型循环。但是不管哪一种形式,循环程序都是由以下三部分组成: (1)循环初始化部分:为循环做准备工作,如设置循环次数,设置循环体需要的初始值以及控制循环的结束条件等。 (2)循环体部分:这是循环工作的主体,是需要重复执行的部分。其中也包括对循环条件进行修改的程序段。如果循

2、环体中不包括其它的循环程序,则为单重循环结构,否则称为多重循环结构。 (3)循环控制部分:根据循环结束条件判断是否继续循环。在循环次数已知的情况下,可用循环次数作为循环结束的条件,后面介绍的LOOP指令使这种循环很容易实现,这种循环属计数型循环;但是当循环次数未知时,就必须根据具体情况选择合理的结束条件,保证程序正常退出循环,这种循环属条件型循环。第2页/共58页以下的流程图很好地说明了这两种循环结构。 图5-1所示为计数型循环,图5-2所示为条件型循环。 实际应用中,我们可以将循环控制部分放在循环体之前进行,形成“先判断、后循环”的结构形式,也可以将循环控制部分放在循环体之后,形成“先循环、

3、后判断”的结构形式。读者可以根据需要灵活掌握。下面分别举例说明计数型循环和条件型循环的控制方法。CX循环次数循环体CX循环次数-1(CX)=0NY退出循环图5-1 计数型循环结构图5-2 条件型循环结构循环初始化部分循环体(包括工作部分和修改循环条件)循环条件是否满足NY退出循环第3页/共58页例5-1:已知有n 个8位有符号二进制数,存放在以BUF为首址的字节存储区中,试统计其中正数的个数。 分析:每个元素是一个8位有符号二进制数,因此要判断其是否为正数,需选择带符号数条件转移指令进行判断转移。由于共有n个元素,因此整个程序的结构就是对以上判断重复n次,故选用计数型循环程序实现。 存储单元及

4、寄存器分配如下: BX:BUF存储区的地址指针,初值为BUF的偏移地 址,每循环一次之后,其值加1。 CX:循环计数器,初值为BUF存储区中元素的个数n, 每循环一次之后,其值减1。 AX:用来存放正数的个数,初值为零。 字变量COUNT:用来最终存放正数的个数。 程序流程图如图5-3所示:第4页/共58页开始BXBUF的偏移地址CXBUF区中元素个数AX0(BX)0AX(AX)+ 1BX(BX)+ 1CX(CX)- 1(CX)=0COUNT(AX)结束YYNN循环初始部分循环体部分循环控制部分图5-3 统计正数个数程序流程图第5页/共58页源程序如下:STACK SEGMENT STACK

5、DB 200 DUP(0)STACK ENDSDATA SEGMENTBUF DB 8,10,-5,100,-7,25,40N =$BUF ;BUF区中元素个数COUNT DW ?DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXLEABX,BUFMOVCX,N ;循环初始部分MOVAX,0AGAIN:CMPBYTE PTR BX, 0JLENEXTINCAX ;循环体部分NEXT: INCBXDECCXJNZAGAIN ;控制部分MOVCOUNT,AX ;将正数个数送入COUNT中MOVAH

6、,4CHINT21HCODEENDSENDBEGIN第6页/共58页 该程序的循环体被重复执行了n次,即当(CX)= n,n-1,1时循环执行,当(CX)= 0时结束循环,将正数个数5送入字变量COUNT中。 对这种计数型循环,为了控制循环结束,在进入循环前要先确定循环次数,以后每循环一次就修改计数值,当计数值为零时就结束循环。 读者可以思考以下问题: (1)在循环初始部分,如果将循环次数的负值送入循环计数器CX中,即“MOV CX ,n”,应该如何修改循环体部分和循环控制部分? (2)如果将0送入循环计数器CX中,即“MOV CX ,0”,应该如何修改程序呢? (3)如果要分别统计出正数、零

7、、负数的个数,应如何设计程序?第7页/共58页例5-2:统计寄存器BX中1的个数,结果存放在COUNT单元中。 分析:要统计BX中1的个数必须进行逐位测试。首先判断最高位是否为1,然后用移位的方法把各位逐次移到最高位进行判断。循环的结束条件可用计数值16来控制,也就是可以用计数型循环来设计。但这种方法的缺点是无论BX中有没有1都必须循环16次。 下面我们用条件控制法,即通过测试BX的值是否为零作为结束条件,这样可以大大缩短循环次数。 存储单元及寄存器分配如下: BX:要测试的寄存器。 CX:用来存放1的个数,初始值为0。 字变量COUNT:用来最终存放1的个数。 程序流程图如图5-4所示:第8

8、页/共58页开始(BX)= 0(CX)0SF=0CX(CX)+1(BX)左移一位COUNT(CX)结束NYYN图5-4 统计BX中1的个数程序流程图第9页/共58页源程序如下:STACK SEGMENTSTACK DB 200 DUP(0)STACK ENDSDATASEGMENTCOUNTDW?DATAENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVCX,0 ;CX0NEXT:ANDBX,BX ;测试BXJZEXIT ;(BX)= 0,结束循环转EXITJNSNEXT1 ;SF = 0转NE

9、XT1INCCX ;否则CX (CX)+1NEXT1:SHLBX,1 ;(BX)左移1位JMPNEXT ;转NEXT继续循环EXIT: MOVCOUNT,CX ;COUNT1的个数MOVAH,4CHINT21HCODE ENDSENDBEGIN第10页/共58页 本程序在运行前并不知道BX的值。若全为0,则不必循环,直接转EXIT结束程序。若只有最高位为1,则执行“INC CX”后,左移一位,再转NEXT处判断,此时(BX)=0转EXIT结束程序,仅需执行一次循环。只有最低位为1时才需通过16次执行循环体,统计出BX中的个数。显然,此处用条件控制循环效率最高。 另外,本题在测试某位是否为1时,

10、也可以将最高位左移,通过判断CF是否为1来实现。第11页/共58页5.2 循环指令 为了简化循环程序的设计,8086/8088专门设置了一组循环指令:LOOP、LOOPZ/LOOPE和LOOPNZ/LOOPNE。这些循环指令在执行前,必须预先将循环次数存放在CX寄存器中。另外这些循环控制指令只能实现短转移,即相对于当前IP值,转移范围为128 127个字节。循环执行均不影响状态标志位。 下面分别介绍各条循环指令:第12页/共58页1LOOP 循环指令 格式:LOOP 标号 功能: CX(CX)- 1 ; 判断CX的值,若(CX)0转移到标号处继续循环;否则退出循环。 例5-3:计算1 + 2

11、+ 3 + + 100,并将结果存入字变量SUM中。第13页/共58页分析: 这是一个典型的计数型循环用于求累加和问题。循环体执行次数已知(=100)。 程序流程图如图5-5所示: 存储单元及寄存器分配如下: AX:用来存放累加和,初值为0。 CX:用来存放循环次数,初值为100,每次减1。 SUM:用来存放最终结果的字变量。开始AX0CX100AX(AX)+(CX)CX(CX)1(CX)=0SUM(AX)结束NY图5-5 求累加和的程序流程图第14页/共58页源程序如下:STACK SEGMENTSTACK DB200DUP(0)STACK ENDSDATASEGMENTSUMDW?DATA

12、ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVAX,0;AX清零MOVCX,100;CX循环次数100NEXT:ADDAX,CX;求累加和LOOPNEXT;MOVSUM,AX;将累加和送入字变量SUM中MOVAH,4CHINT21HCODE ENDS END BEGIN第15页/共58页 程序运行后,在字变量SUM中保存的值是5050。思考:(1)程序中“LOOP NEXT”语句可以用哪两条语句来代替?(2)若要求从1开始连续50个奇数的和,应如何编程?第16页/共58页2LOOPZ/LOO

13、PE为零或相等时循环指令。 格式:LOOPZ/LOOPE 标号 功能: CX (CX)-1 ; 判断CX和ZF值,若(CX)0且ZF = 1转移到标号处继续循环;若(CX)= 0或ZF = 0则退出循环。第17页/共58页3LOOPNZ/LOOPNE不为零或不相等时循环指令 格式:LOOPNZ/LOOPNE 标号 功能: CX(CX)-1 ; 判断CX和ZF值,若(CX)0且ZF = 0转移到标号处继续循环;若(CX)= 0或ZF = 1则退出循环。 LOOPZ/LOOPE和LOOPNZ/LOOPNE指令提供了提前结束循环的可能性。第18页/共58页例5-4:已知在以BUF为首址的字节存储区中

14、存放着一个有N个字符的字符串。试编写程序在字符串中查找第一次出现的字符“E”(ASCII码为45H)。若找到将其偏移位置存入FOUND单元;否则在屏幕上显示“NO FIND!”。 分析:本题目要求在一字符串中查找某一字符,查找方法有多种,这里采用顺序查找方法。若找到将其偏移位置保存起来,结束程序;否则显示一提示信息。 存储单元与寄存器分配如下: SI:BUF存储区中字符的偏移位置,初值为1,每次递增1。 AL:用来保存要查找的字符。 CX:来存放循环次数,初值为字符串长度,每次减1。 BUF:用来存放字符串的存储区。 FOUND:用来存放查找成功时字符的偏移位置。第19页/共58页源程序如下:

15、STACKSEGMENT STACK DB 200DUP(0)STACKENDSDATASEGMENTBUFDBHELLO,MY FRIEND!N = $ - BUFFOUND DW?NOFINDDB 0DH,0AH,NO FIND!$DATAENDSCODESEGMENT ASSUME CS:CODE,SS:STACK,DS:DATABEGIN:MOVAX,DATAMOVDS,AX MOV CX,N;CX 字符串长度N MOV SI,-1;初始化下标变量 MOV AL,45H;AL 要查找字符的ASCII码 NEXT:INCSICMPAL,BUFSI;判断是否是要找的字符LOOPNE NEX

16、T;如果ZF=0且(CX) 0,则转NEXT继续循环JNZNO_FIND ;如果ZF=0,则查找不成功,转NO_FINDMOV FOUND,SI ;如果ZF=1,查找成功,将偏移位置送给FOUND单元 JMP EXITNO_FIND: MOVDX,OFFSET NOFINDMOVAH,9;显示“NO FIND!”提示信息INT21HEXIT:MOVAH,4CHINT21H;程序结束CODEENDSENDBEGIN第20页/共58页 在程序执行过程中,有两种可能性: (1)在查找过程中成功找到字符“E”,此时ZF=1提前退出循环。执行JNZ指令时因不满足测试条件而执行指令“MOV FOUND,S

17、I”。 (2)一直查找到字符串结束而未发现字符“E”,则因(CX)= 0而结束循环。在执行JNZ指令时,因ZF=0而转NO_FIND去执行。第21页/共58页5.3 循环程序设计方法 循环程序按结构可分为单重循环程序和多重循环程序,下面分别进行介绍。5.3.1 单重循环程序设计 所谓单重循环,就是其循环体内不再包含循环结构的程序。第22页/共58页例5-5:假设在以BUF为首址的存储单元中存放着一串字符,找出其中ASCII码最大的字符,并存入MAX单元中。 分析:在一串字符中要寻找最大值,我们可以首先假设第一个字符就是最大字符,将其存入AL单元中。然后从第二个字符开始依次与AL比较,若某个字符

18、比AL还大,则将其赋给AL,这样比较下去,最后在AL中保存的就是最大字符。 存储单元与寄存器分配如下: CX:循环次数控制变量,初值为字符串的长度1,每次减1。 BX:BUF存储区地址指针,初值指向BUF,每次加1。 AL:用来求最大值的工作单元,保持某个时刻的最大值。 MAX:用来保存最终结果的字节单元。 程序流程图如图5-6所示:Y开始BXBUF存储区首地址AL字符串中第一个字符CX字符串长度减1BX(BX)+1ALBXCX(CX)-1AL(BX)(CX)= 0MAX(AL)结束NYN图5-6 求最大字符的程序流程图第23页/共58页源程序如下:STACKSEGMENT STACK DB2

19、00DUP(0)STACKENDSDATASEGMENTBUFDBABCD5678bdcaMNN = $ - BUFMAXDB?DATAENDCODESEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVBX,OFFSETBUF;BX指向字符串首MOVAL,BX;取出第一个字符MOVCX,N-1;比较次数送CXNEXT1:INCBX;BX指向下一字符CMPAL,BX;比较JNCNEXT2MOVAL,BX;大数送ALNEXT2:LOOPNEXT1;循环次数(CX) 0继续循环MOVMAX,AL;MAX最大数MOVAH,

20、4CHINT21H CODEENDSENDBEGIN程序运行后,在MAX单元中保存的字符是“d”。第24页/共58页例5-6:试编制一个程序把NUM字存储单元中的二进制数用十六进制数的形式在屏幕上显示出来。 分析:我们可以把NUM字单元中的内容从左到右每4位为一组,在屏幕上显示出来,这可以用循环结构实现,每次显示一个十六进制数,共循环4次。在循环体内完成把四位二进制数转换为一个十六进制数字的功能。这里采用循环移位的方法把要处理的四位二进制数移到最右端。然后进行数字到字符的转换工作。若是数字0 9,直接将其ASCII码加30H就转换成字符09;若是字母AF,除将其ASCII码加30H外,还应加上

21、07进行调整,才能转换成AF。第25页/共58页 DI:用来指向保存转换结果的存储单元,每次加1。 BX:用来保存要转换的二进制数的工作单元。 CH:循环计数器,初值为4,每次减1。 CL:循环移位次数,每次移4位。 AL:转换中用到的工作单元。 程序流程图如图5-7所示: 源程序如下:DATASEGMENTNUMDW0010110100111001BBUFDB0AH,0DH,(NUM)= BUF0DB6 DUP(?)DATAENDSSTACKSEGMENT STACK DB200DUP(0)STACKENDS图5-7 二进制转换成十六进制的程序流程图开始初始化工作将BX循环左移四位是否大于9

22、Y将转换结果送存储区保存加07调整循环计数器为0显示转换结果结束NYN取BX低四位转换成ASCII码存储单元及寄存器分配如下:第26页/共58页CODESEGMENT ASSUME CS:CODE,SS:STACK,DS:DATABEGIN:MOVAX,DATAMOVDS,AXMOVBX,NUM ;要转换的二进制数送入BXLEADI,BUF0 ;保存转换结果的存储单元首址送DIMOVCH,4 ;CH循环次数NEXT: MOVCL,4 ;CL循环移位次数ROLBX,CL ;每次将要处理的4位二进制数移到最低位MOVAL,BL ;取BX的低字节送ALANDAL,0FH ;取出最低4位ORAL,30

23、H ;转换成十六进制CMPAL,3AHJLDONE ;9 时转移ADDAL,07H ;若大于加07调整DONE: MOVDI,AL ;将转换后的十六进制数送BUF0存储区保存INCDI ;指向下一存储单元DECCH ;CH (CH)1JNZNEXT ;若(CH) 0转NEXT继续转换MOVBYTE PTRDI,H;否则在转换完的十六进制数后加HINCDI ;MOVBYTE PTRDI,$LEADX,BUFMOVAH,9 INT21H MOVAH,4CHINT21HCODEENDS ENDBEGIN程序运行后,在屏幕上显示: (NUM)= 2D39H第27页/共58页例5-7:已知在以BUF为首

24、址的字节存储区中,存放着一个以$作为结束标志的字符串,试编写程序完成下列功能:统计其中小写字母的个数并存入COUNT单元中;在屏幕上显示该字符串,并要求将小写字母以大写字母形式显示出来。第28页/共58页分析: 本题目中没有直接给出字符串的长度,而是给出了字符串的结束标志。因此我们可以选用条件控制法来控制循环的执行。每当从存储区中取出一个字符后,首先判断是否是字符$,若是,则结束循环的执行。否则,判断是否为小写字母,若是,先将累加器加1,再将小写字母转换成大写字母(ASCII码减去20H)送显示器显示;若不是小写字母,则直接送显示器显示。 程序流程图如图5-8所示: 存储单元和寄存器分配如下:

25、 BX:指向BUF存储区的地址指针,每次加1。 AX:用来保存小写字母个数的工作单元。 DL:存放要显示字符的工作单元。 COUNT:用来最终保存小写字母个数的字变量单元。第29页/共58页开始AX0BXBUF的偏移地址DL(BX)(DL) =$(DL)为小写字母小写字母转换成大写字母AX(AX)+1显示DL中字符BX(BX)+1COUNT(AX)结束YNYN图5-8 小写字母统计及字符串显示的程序流程图第30页/共58页源程序如下:STACKSEGMENT STACK DB200DUP(0)STACKENDSDATASEGMENTBUFDB This is a Assembly Progra

26、m.$COUNT DW ?DATAENDSCODESEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOV AX,0 ;AX清0LEABX,BUF ;BX BUF的偏移地址NEXT: MOVDL,BX ;从存储区中取一字符送入DL中CMPDL,$ ;若为结束标志$,则转EXITJEEXITCMPDL,aJBDONE ;若不是小写字母,则转DONE直接显示CMPDL,z JADONESUBDL,20H ;将小写字母转换成大写字母INCAX ;计数器加1DONE: MOVAH,2INT21HINCBX ;指向下一个字符,继

27、续循环JMPNEXTEXIT: MOVCOUNT,AX ;循环结束,将小写字母个数写入COUNT单元MOVAH,4CHINT21HCODEENDSENDBEGIN第31页/共58页 程序运行后,COUNT单元中的内容为19(=13H)。 屏幕上显示:THIS IS A ASSEMBLY PROGRAM 下面我们再介绍一个用单重循环结构实现顺序查找的程序。第32页/共58页例5-8: 假设在以TAB为首址的字节存储区中,存放着n 个学生汇编语言的期末考试成绩。 其中学号顺序是随机的。现需要在表中查找某个学号对应的汇编语言成绩,若查找成功,则将该学号的偏移地址送SI,对应成绩送DH寄存器,并将字节

28、变量FLAG置1;否则将FLAG清0,表示查询失败。第33页/共58页分析: 要在一批数据中查找满足条件的值,最简单的办法就是采用顺序查找法。从第一个数据开始逐一进行比较。如果找到满足条件的值,就跳出循环,取出信息送入指定寄存器,并执行相应操作;否则顺序向下查找,如果查找遍所有n 个数据仍未找到,则结束循环,查找失败。 具体实现时可在数据存储区中建一个表,表中每一项根据实际情况占若干字节,本例中对每个学生只有学号和成绩两个值,因此每项可占两个字节,有n 个学生,共占2n个字节。 存储单元和寄存器分配如下: N:用来存放TAB表的总项数。 CX:循环计数器,初值为N,每次减1。 BX:指向表TA

29、B的地址指针,每次增2。 AL:用来存放要查找的学号。 SI: 查找成功时用来保存学号的偏移地址。 DH:查找成功时用来保存对应成绩信息。 FLAG:标志变量,1表示查找成功,0表示失败。 NUM:用来存放要查找的学号。第34页/共58页程序流程图如图5-10所示:BXTAB的偏移地址CXNAL要查找的学号(AL) = (BX)BX(BX)+2CX(CX)-1(CX)=0FLAG0结束SI(BX)DH(BX+1)FLAG1NNYY开始图5-10 顺序查找流程图第35页/共58页源程序如下:STACKSEGMENT STACK DB 200 DUP(0)STACKENDSDATASEGMENTT

30、AB DB 5,90,8,75,2,80,6,78,15,84,3,95,12,86,20,92N ($ TAB)2;表TAB中的总项数NUMDB6 ;要查找6号学生的成绩信息FLAGDB?DATAENDSCODESEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXLEABX,TAB ;BXTAB的偏移地址MOVCX,N ;CXNMOVAL,NUM ;AL待查找的学号NEXT: CMPAL,BX JEDONE ;(AL)=(BX),查找成功转DONEADDBX,2 ;否则BX增2,指向下一项DECCX ;CX (CX)1

31、JNENEXT ;(CX) 0,继续查找MOVFLAG,0 ;否则FLAG0,查找失败JMPEXITDONE: MOVSI,BX ;SI已找到学号在表中的偏移位置MOVDH,BX+1 ;DH对应的成绩MOVFLAG,1 ;FLAG1,表示查找成功EXIT: MOVAH,4CHINT21HCODEENDSENDBEGIN第36页/共58页 本程序运行后,有 (SI)= 6,(DH)= 4EH,(FLAG)= 1 读者可自己分析程序的执行过程。 另外,还可思考以下几个问题: 若TAB表中除汇编成绩外,还有英语、数学两个成绩,每个数据项应分配几个字节?如何实现? 若要查找的学号不是在数据段中直接给出

32、,而是需要在程序运行时通过键盘即时输入,应如何实现? 若查找成功时,要求把学号和成绩直接在屏幕上显示出来,应如何实现?第37页/共58页 以上通过几个例子介绍了单重循环程序的设计方法,若循环次数已知,可用计数型循环来实现,若循环次数未知,可通过条件型循环来控制。不论哪种形式,其循环体内都只有顺序结构和分支结构两种形式。但在实际应用中,我们还会碰到更复杂的循环体中又包含循环结构的情况,这种循环体中又包含循环结构的程序叫做多重循环程序。第38页/共58页5.3.2 多重循环程序设计 多重循环即循环体内又嵌套有循环。多重循环程序设计的基本思想和单重循环程序设计是一致的,但实现起来更复杂一些。应分别考

33、虑各重循环的控制条件及其程序实现,相互之间不能混淆,即内外层循环必须是嵌套的形式,不能出现交叉。 下面举例说明多重循环程序设计的方法和特点。第39页/共58页例5-9:在以BUF为首址的字节存储区中存放有n个无符号数x1,x2, xn,现将它们按由大到小的顺序排列在BUF存储区中,试编程实现。 分析:本例题是对n个数据进行排序问题。排序是计算机程序设计中的一种重要算法,关键值按从小到大排列称为升序,从大到小排列称为降序。排序的方法有很多,如选择排序、冒泡排序、插入排序、shell排序等等。下面我们首先介绍比较简单的选择排序。第40页/共58页选择排序算法如下(按降序排列): 若一组数据放在n个

34、存储单元中,首先进行第一轮比较,将第一个存储单元中的数与其后n-1个存储单元中的数依次进行比较,若两个数不满足降序排列,则将两者交换,即总是将两数中的大数放在第一个存储单元中,这样经过n-1次比较后,n个数中的最大者就存入第一个存储单元之中,其中n-1次比较可以用一个计数型循环来控制;接着进行第二轮比较,将第二个存储单元中的数与其后的n-2个存储单元中的数依次比较,不满足降序则交换,这样经过n-2次比较后,n个数中的第二大者就存入第二个存储单元之中,如此重复下去,直到第n-1轮比较完成后,将n个数中的第(n-1)大者存入第n-1个存储单元,剩下第n个存储单元中的数据自然就是n个数中的最小者,这

35、样经过n-1轮比较就可以实现n个数据由大到小降序排列。从第一轮到第n-1轮的控制又可以用一个计数型循环来实现。这样整个程序就可以用一个二重循环来控制实现。其中外循环用来控制是第几轮比较,即要找第几个位置上的最大值,内循环用来控制如何找到这个最大值。第41页/共58页例如,有如下4个数据: 60 27 96 43现要将它们按从大到小的次序重新排列。 4个数的排序需要经过3轮比较才能完成。 第一轮:将第一个存储单元中的数据60作为最大值,依次与后面的数据比较,不满足降序则交换。经过三次比较最终求出第一个位置上的最大值96。 第一次:60 279643 6027不需交换 第二次:96 276043

36、6043不需交换 第二轮:求出第二个位置上的最大值60,需经过两次比较。 第一次:96 602743 2743不需交换 第三轮:求出第三个位置上的最大值43,只需经过一次比较。 第一次:96 604327 2743进行交换 至此,4个数据已排成递减序列。第42页/共58页 本题目实现的程序流程图如图5-11所示: 存储单元和寄存器分配如下: SI:用来控制外循环的循环计数器,初值为1,终值为N1,每次递增1。 DI:用来控制内循环的循环计数器,初值为(SI)+1,终值为N,每次递增1。 AL:用来存放比较数据的寄存器。 BUF:存放要排序数据的存储单元。 N:存放要排序数据的个数。第43页/共

37、58页开始SI1DI(SI)+1AL(BUF+(SI)-1)(AL) (BUF+ (DI) -1)AL与(BUF+(DI)-1)互换BUF+(SI)-1(AL)DI(DI)+1(DI)NSI(SI)+1(SI)N-1结束YYYNNN图5-11 选择排序算法流程图第44页/共58页源程序如下:STACKSEGMENT STACKDB 200 DUP(0)STACKENDSDATASEGMENTBUF DB 0AH,8,15H,36H,6,20H,12HN = $BUF;N为要排序数据的个数DATAENDSCODESEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKBEG

38、IN:MOVAX,DATAMOVDS,AXMOVSI,1 ;给外循环计数器赋初值1NEXT1:MOVDI,SI ;内循环计数器初值从(DI)=(SI)+1开始INCDIMOVAL,BUF+SI-1 ;AL(BUF+(SI)1)NEXT2:CMPAL,BUF+DI-1 ;进行比较,若满足降序转NEXT3JAENEXT3XCHGBUF+DI-1,AL ;否则交换两数MOVBUF+SI-1,ALNEXT3:INCDI ;(DI)(DI)+1CMPDI,N ;若(DI)N转NEXT2,继续执行内循环开始 JBE NEXT2 ;否则退出内循环,本轮循环结束,准备进入下一轮循环INCSI ;(SI)(SI

39、)+1CMPSI,N-1 ;比较(SI)与N1JBE NEXT1 ;若(SI)N-1转NEXT1继续下一轮循环,否则退出外循环结束程序。 MOV AH,4CHINT21HCODEENDSENDBEGIN第45页/共58页 程序运行后,BUF存储区中的内容如下: 36H,20H,15H,12H,0AH,8,6 执行过程,读者可自行分析。 思考: 本例题是对存储单元中的N个无符号数进行比较排序,若要对N个有符号数排序应如何实现? 若要对数据进行升序排列应如何实现?第46页/共58页下面再简单介绍冒泡排序的基本算法(以升序为例)。 冒泡排序是一种比较典型的排序算法,具体实现时是从第一个元素开始,依次

40、对N个元素中相邻的两个元素进行比较,若顺序不满足则进行交换,这样经过一轮比较后,最大的元素就排到了最后面;然后进行第二轮,仍然从第一个元素开始,依次对除最后一个元素外的N-1个元素中相邻的两个元素进行比较,若顺序不满足则进行交换,这样经过第二轮比较后第二大元素就排在了倒数第二个位置,如此重复,直到所有的元素都排序完毕。可见,冒泡程序也是一个双重循环程序结构。第47页/共58页例如:要对以下数据进行升序排列49352897 76 1327第一轮: 35 49 28 97 76 13 27 第一次比较49与35,不满足升序,交换。35 28 49 97 76 13 27 第二次比较49与28,不满

41、足升序,交换。35 28 49 97 76 13 27 第三次比较49与97,升序满足,不交换。35 28 49 76 97 13 27 第四次比较97与76,不满足升序,交换。35 28 49 76 13 97 27 第五次比较97与13,不满足升序,交换。35 28 49 76 13 27 97 第六次比较97与27,不满足升序,交换。这样,经过第一轮比较后,最大值97就“冒”到了最后一个位置。第二轮后:28 354913277697次大值76就出现在倒数第二个位置。第三轮后:28 351327497697第四轮后:28 132735497697第五轮后:13 272835497697第六

42、轮后:13 272835497697这样经过六轮比较后,所有数据已按升序排列。第48页/共58页 以上介绍了冒泡排序的设计思想,读者可自己编写出源程序。另外,为了提高排序效率,我们还可以对算法进行改进,以减少不必要的循环次数。有兴趣的读者可以查阅相关资料。 排序和查找是程序设计中比较典型的算法。前面我们曾介绍了一种顺序查找算法,下面我们再来介绍一种在已排好序的数组中查找某个值的有效算法折半查找法,或叫二分查找法。第49页/共58页 例5-10:假设在以BUF为首址的字节存储区中,存放着一个已按由小到大顺序排列的无符号数的数组,要求在数组中查找X,如找到则将该元素在数组中的偏移位置存入Y中,并显

43、示“OK!”,否则显示“NO!”。第50页/共58页折半查找算法的基本思想: 折半查找算法就是首先取有序数组的中间元素(设为Mid),将其与要查找的值X进行比较,若相等则查找成功。若不相等则需要判断X是在前半部分还是在后半部分,如果X大于中间元素Mid,则在后半部分继续查找,取后半部分的中间元素与X相比较;如果X小于中间元素,则在前半部分继续查找,即取前半部分的中间元素与X相比较。如此重复直到查找成功或最终未找到该数(查找失败)为止。 折半查找法的效率要远远高于顺序查找法,对于长度为N的数组,顺序查找法平均要做N/2次比较,而折半查找法的平均次数约为log2N。例如,对于长度为1024的数组,

44、顺序查找法最多要用1024次比较才能得出结果,而折半查找法最多用10次比较就可得出结论。第51页/共58页 程序流程图如图5-12所示: 存储单元及寄存器分配如下: SI:保存BUF存储区中最小元素的偏移地址。 DI:保存BUF存储区中最大元素的偏移地址。 CX:用来存放数组的长度。 AL:用来保存要查找的数据X。 BL:用来存放BUF存储区中的中间元素。 Y: 用来保存查找成功时元素的偏移位置。第52页/共58页开始SI0,CXN,ALX,DIN-1(AL) (BL)DI(DI)-(CX)(SI)(DI)SI(SI)+(CX)CX(DI)-(SI)显示“No!”结束YYNNNY图5-12 折

45、半查找算法流程图(CX)是偶数CX(CX)-1NY第53页/共58页源程序如下:STACKSEGMENT STACKDB200DUP(0)STACKENDSDATASEGMENTBUF DB 23,34,45,50,56,67,78,89,91N = $ - BUFX DB 45YDB ?BUF1 DB OK!$BUF2 DB NO!$DATAENDSCODESEGMENTASSUME CS:CODE,DS:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVSI,0;SI指向第一个元素 MOV CX,N ;CX已排序元素的个数MOVAL,X;AL要查找数据MOVD

46、I,-1 ADD DI,CX;DI指向最后一个元素CMPAL,BUF+SI;AL与第一个元素比较JBFAIL;若AL小,则查找失败CMPAL,BUF+DI;AL与最后一个元素比较JAFAIL;若AL大,则查找失败第54页/共58页AGAIN:TEST CX,1 ;测试元素个数是否为偶数 JZ NEXT ;是偶数转NEXT DEC CX ;否则CX(CX)-1NEXT: SHRCX,1;CX(CX)/2MOVBL,BUF+SI+CX;BL求出中间元素CMPAL,BL;(AL)与(BL)比较JZSUCCESS;若(AL)=(BL)查找成功JANEXT1;若(AL)(BL)转NEXT1SUBDI,C

47、X ;否则将DI前移JMPNEXT2NEXT1:INC SI ADDSI,CX ;将SI后移NEXT2:CMPSI,DI ;比较SI与DIJAFAIL ;若SI大于DI,则查找失败MOVCX,DI SUB CX,SI ;将查找范围缩小一半,继续查找JMPAGAINFAIL: MOVDX,OFFSETBUF2 MOVAH,9 ;若查找失败,则显示“NO!”提示信息INT21HJMPEXITSUCCESS:ADDSI,CXMOVY,SI ;若查找成功,将元素偏移位置送Y单元MOVDX,OFFSETBUF1 ; 并显示“Ok!”提示信息MOVAH,9INT21HEXIT: MOVAH,4CHINT21HCODEENDSENDBEGIN第55页/共58页 如要在下列数组中查找x = 45,23 34 45 50 56 67 78 89 91 则在Y存储单元中保存偏移量2,在屏幕上显示“OK!”。第56页/共58页本章小结 本章主要介绍了循环程序的基本结构、设计思想及循环程序设计方法。通过本章的学习,要求读者掌握循环程序的一般结构形式和循环指令,深刻理解计数型循环与条件型循环的区别。熟练掌握单重循环和多重循环程序设计方法。第57页/共58页感谢您的观看。第58页/共58页

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > PPT文档

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁