资源预览内容
第1页 / 共38页
第2页 / 共38页
第3页 / 共38页
第4页 / 共38页
第5页 / 共38页
第6页 / 共38页
第7页 / 共38页
第8页 / 共38页
第9页 / 共38页
第10页 / 共38页
亲,该文档总共38页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第四章 程序篇-循环与分支程序设计,循环程序的结构形式,程序有顺序、循环、分支和子程序四种结构,本章说明循环与分支程序结构。 有二种结构形式: (见下页),do_WHILE 结构(循环次数可能为0) 循环控 y 制条件 循环体 N 先判条件,满足条件则执行循环体,否则退出。,循环初始状态,循环体,循环控制 条件,N,Y,do-UNTIL结构 先执行循环体,后判断条件,满足条件,则循环,否则退出。,不论哪种结构形式,循环程序可由如下三部分组成: 1)设置循环的初始状态。如设置循环计算值等。 2)循环体。循环工作的主体,它由循环的工作部分及修改部分组成。 3)循环控制部分:合理地选择循环控制条件是循环程序设计的关键。,循环程序设计方法,编程步骤如下: 1、分析题意,确定算法。 (仔细分析和理解题意,找出合理的算法及适当的数据结构) 2、根据算法画出程序框图。 3、依框图编写程序. 4、上机调试程序-检查你的设计思想是否正确以及你的程序是否符合你设计思想。,09, AF 3039H,4146H,例1:编制一个程序把BX寄存器的二进制数用十六进制数在屏幕上显示出来。 步骤:1、分析提意,选择算法。 分析:二进制数 (十六进制数) 16进制数的ASC码 屏幕显示出正确的十六进制数,算法: 1)将BX内的十六进制数分成4组,(即4个十六进制数)。 2)从最高位组开始进行转换,若9(即3aH),则将该组值加上37H,并将结果显示出来,然后再转换次高位组,依次循环4次。 3)最高位组移到AL中的低四位,以使计算用循环左移形成。 MOV CL,4 ROL BX,CL MOV AL,BL,2、画框图: 1 2 (续下页),开始,初始化 MOV CH,4,BX 循环左移,将最右边的转换 成ASCII码,ASCII的A-F?,加7,显示一个字符调用 DOS的02号功能,循环计算数=0,结束,(续上页),1,2,y,N,N,y,3、写出源程序 Program segment assume cs:program Start: mov bx, 468ah mov ch, 4 rotate: mov c1,4 rol bx,c1 mov a1,b1 and a1,0fh add a1,30h cmp a1,3ah jl print add al,7h,Print: mov dl,al mov ah,2 int 21h dec ch jnz rotate mov ah,4ch int 21h Program ends end start,注意: 1、该程序中,未用LOOP指令,而是用DEC CH和JNZ rotate来完成的。 2、本例为do-until结构。,例2: 在ES段中有一个首地址为LIST和未经过排序的字数组,在数组的第一个字中存放着该数组的长度,数组的首地址已放入DI寄存器中,AX中存放着一个数。要求编一个程序:在数组中查找该数,如果找到此数则把它从数组中删除。,分析:先找是否有(AX)在数组中,若无则结束程序。用串处理指令REPNZ SCASW,若找到,则应将数组中找出的元素的后面所有的字(即高于该元素地址的字)前移(向低地址方向)一个字的位置。用循环结构完成。,开始,用串处理指令 查找(AX),找到AX,是末元素,Y,N,前移一个字,数组结束否,修改数组长度,结束,N,Y,Y,N,画框图,写程序: del-ul proc far cld push di mov cx,es:di add di,2 repne scasw je delete pop di jmp short exit,Delete: jcxz dec_cnt next_el:mov bx,es:di mov es:di-2,bx add di,2 loop next_el dec_cnt:pop di dec word ptr es:di exit: ret del_ul endp,注意: 1)设置DF=0,CLD 2)保存首地址以便修改数组的个数 3)next-el:将高地址里的内容覆盖删除部分,下面介绍在循环程序设计中设立标志位的方法,这种标志位是为了正确执行所做操作面设立的,其中有一种常用的方法称为逻辑方法,例3 设数组X和Y,X数组中有x1,x10 Y=(y1,y10)编程计算 Z1=x1+y1,Z2=x2+y2,Z3=x3-y3 Z4=x4-y4,Z5=x5-y5,Z6=x6+y6 Z7=x7-y7,Z8=x8-y8,Z9=X9-Y9 Z10=x10+y10 结果存入Z数组,解:尽管每个算式不相同,也可用循环结构来完成:循环数值为10,所做的操作有二种加法,减法。为了区别每次操作是加还是减,我们设置标志位: 如果标志位为0 加法 如果标志位为1 减法,本题有10次操作,则应该设10个标志位,故用二个字节来表示(16位,最高6位无意义设为0)。并将它存入存储单元中,该存储单元称为逻辑尺单元名设为LOGIC-RULE 其内容为:0000000111011100=01dcH,开始,初始化CX=10,i=1,测逻辑尺第i位,xi+yi,xi-yi,Zi 结果,i I+1,CX=0?,结果,=0,=1,画框图,写程序 datarea segment x dw x1,x2,x3,x4,x5,x6,x7,x8,x9,x10 y dw y1,y2,y3,y4,y5,y6,y7,y8,y9,y10 z dw z1,z2,z3,z4,z5,z6,z7,z8,z9,z10 logic_rule dw 01dch detarea ends program segment,assume cs:program,ds:datarea start: mov ax,datarea mov ds,ax mov bx,0 mov cx,10 mov dx,logic_rule Next: mov ax,xbx shr dx,1 jc subtract add ax,ybx jmp short result,subtract: sub ax,ybx result: mov zbx,ax add bx,2 loop next program ends end start,问:1.用什么方式取得x,y数组中的不同元素? 2.逻辑尺是如何实现它的判断功能的(用的 什么指令)? 3.逻辑尺中最高位是无意义的,这对程序的 执行有无影响?为什么?,多重循环程序设计,循环可以有多重结构。它的基本方法与单重循环程序设计是一致的: 1. 分别考虑各重循环的控制条件及其程序实现,相互之间不能混淆。 2. 在每次通过外层循环再次进入内层循环时,初始条件必须重置。,例4、 有一个地址为A的N字数组,请编制程序使该数组中的数按从大到小的次序 排列。 算法:采用起泡排序法: 第一遍比较(N-1)次,将最小的数放到最后。 第二遍比较(N-2)次,将最小的数放到倒数第二位。 . . . 最多比较N-1遍,看程序如何实现多重循环: mov cx,n; 置循环初始为n dec cx; 循环次数减1 Loop1:mov dx,cx; 保存内层出值 mov bx,0; 取数组:从第一个开始 Loop2:mov ax,abx cmp ax,abx+2;前后两字比较 jge continue; abx=abx+2则转移 xchg ax,abx+2 mov abx,ax continue:add bx,2;为取下一个数作准备,loop loop2 mov cx,dx;修改内层循环记数值:原始初值放入cx。 loop loop1; 将(cx-1) cx;这样就完成了内层循 环的记数初值的改变,分支程序的两种结构形式,判断条件,分支一,IFTHENELSE,分支二,判断条件,分支一,分支二,分支n,case:,分支程序设计方法,例5,在附加段中,有一个按从小到大顺序排列的无符号字数组,其首地址存放在DI寄存器中可,数组中的第一个单元存放着数组长度,在AX中有一个无符号数,要求在数组中查找(AX),如找到,则使CF=0,并在SI中给出该元素在数组的偏移地址;如未找到则是CF=1,解:对已排序的数组,可用折半查找法以提高效率。 折半查找法:(1)取有序数组的中间元素与查找值比较若相等则查找成功。若大于中间值,则取高半部的中间元素来比较;若小于中间值,则取低半部的中间元素来比较。(2)重复,直到找到为止 (或无该数) 顺序查找需N/2次,折半则为log2 n次,开始,取第一个数,与(AX)比较,取末尾数与 (AX)比较,CF1 退出,找到,退出,未找到,(AX),(AX),=(AX),=(AX),程序框图:,(AX),取数组 中间元素,取低半部的 中间元素,取高半部的 中间元素,与(AX)比较,(AX),=(AX),(AX),(AX),
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号