《2022年循环与分支程序设计知识 .pdf》由会员分享,可在线阅读,更多相关《2022年循环与分支程序设计知识 .pdf(23页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第5章 循环与分支程序设计【课前思考】1.编制一个汇编语言程序分哪几步?2.循环程序有哪两种基本结构?由几部分组成?3.设计算法时对可能出现的边界情况如何考虑?4.如何设置逻辑尺?5.什么是起泡排序算法?6.如何理解数组排序算法中采用的折半查找法?7.如何使用跳跃表法实现CASE结构?【学习目标】了解并掌握循环程序的构造方法,尤其是对循环控制条件的设置以及可能出现的边界情况的考虑。掌握起泡排序算法这种多重循环程序设计中的常用方法。交换标志位的设置在此算法中更能提高效率。学会在数组排序算法中采用折半查找法来提高查找效率。学会使用跳跃表法实现CASE结构。【学习指南】掌握编程的四个步骤至关重要。通
2、过多看举例,学会正确分析理解题意、选择合适的数据结构及算法、坚持先画框图、选取有效指令编程、最后应当掌握运用调试手段进行调试。学习多重循环程序设计前应熟练掌握单层循环程序设计的各种实现方法及实现细节,如对可能出现的边界情况的处理等。学习起泡排序算法、折半查找法、跳跃表法之前,应首先理解传统实现方法。【难重点】循环控制条件的选择。考虑循环算法时注意可能出现的边界情况。静态地预置逻辑尺。动态地修改标志位。多重循环程序设计时应分别考虑各重循环的控制条件及其程序实现,相互之间不能混淆。另外,应该注意在每次通过外层循环再次进入内层循环时,初始条件必须重新设置。起泡排序算法是多重循环程序设计中的一种常用方
3、法。数组排序算法中可以采用折半查找法来提高查找效率。CASE结构可以使用跳跃表法实现。【知识点】名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 23 页 -编制一个汇编语言程序的一般步骤 5.1 循环程序设计 5.1.1 循环程序的基本结构 5.1.2 循环程序设计方法举例循环控制条件边界情况的处理逻辑尺 5.1.3 多重循环程序设计举例起泡排序算法交换标志位 5.2 分支程序设计 5.2.1 分支程序的基本结构 5.2.2 分支程序设计方法举例 折半查找法 5.2.3 跳跃表法一般说来,编制一个汇编语言程序的步骤如下:1)分析题意,确定算法。2)根据算法,画出程序框图。3)根据
4、框图编写程序。4)上机调试程序。名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 23 页 -程序有顺序、循环、分支和子程序四种结构形式。顺序程序结构是指完全按顺序逐条执行的指令序列,这在程序段中是大量存在的,但作为完整的程序则很少见,我们不对它们作专门讨论。5.1 循环程序设计5.1.1 循环程序的结构形式及组成循环程序可以有两种结构形式,如图所示。一种是DO_WHILE结构形式;另一种是 DO_UNTIL 结构形式。初始化:设置循环的初始状态;循环体:循环的工作部分及修改部分;控制条件:计数控制、特征值控制、地址边界控制。名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页
5、,共 23 页 -例5.1试编制一个程序,把BX寄存器中的二进制数以十六进制的形式显示在屏幕上。解析:根据题目要求应将BX中的内容从左到右每4位一组显示出来,共显示 4个十六进制数位。如果显示的数位是09,则把 4位二进制数加上 30H,转换成相应的 ASCII 码30H39H;如果是 AF,则应加上37H(30H+7),转换成 ASCII 码41H46H。显示字符可以使用DOS功能调用来实现。右图是程序框图(P162页)。以binihex.asm 为文件名,建立源程序如下:;binihex.asmprognam segment ;定义代码段main proc far assume cs:pr
6、ognam start:;程序从此处开始执行 ;为正常返回 DOS 而设置堆栈 push ds sub ax,ax 名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 23 页 -push ax;下面是程序的主要部分mov ch,4 ;4 组二进制数rotate:mov cl,4 ;每组4个二进制位rol bx,cl ;把bx循环左移 4位mov al,bl ;暂存bl 到al 中and al,0fh ;仅保留al 的低4位add al,30h ;转换成ASCII码cmp al,3ah ;要显示的数大于 9?jl printit ;如果数在 09之间则显示add al,7h ;数在A
7、F之间则调整printit:mov dl,al ;把要显示字符的 ASCII码送dlmov ah,2 ;功能号2送ahint 21h ;DOS功能调用dec ch ;(ch)-1jnz rotate ;4 组都处理完?否,循环处理下一组ret ;返回DOSmain endp ;主程序main结束prognam ends ;代码段结束end start ;结束汇编例5.2 从键盘接收十进制数并存入 BXprognam segment名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 23 页 -main proc farassume cs:prognamstart:push dssub
8、 ax,axpush axmov bx,0newchar:mov ah,1 ;键盘输入int 21hsub al,30hjl exit ;9 退出cbw例5.3 从键盘接收十六进制数并存入 BXcode segment名师资料总结-精品资料欢迎下载-名师精心整理-第 6 页,共 23 页 -assume cs:code,ds:datastart:mov ax,4c00hint 21h ;返回DOScode endsend start名师资料总结-精品资料欢迎下载-名师精心整理-第 7 页,共 23 页 -例5.4 将正数 N插入一个已整序的字数组的正确位置。该数组的首地址和末地址分别为 ARR
9、AY_HEAD 和ARRAY_END,其中所有数均为正数且已按递增的次序排列。;定义数据段datarea segmentx dw?array_head dw 23,37,49,52,65,78,99array_end dw 105n dw 32datarea ends;定义代码段prognam segmentmain proc far ;主程序部分assume cs:prognam,ds:datareastart:;程序从此处开始执行push dssub ax,axpush axmov ax,datarea名师资料总结-精品资料欢迎下载-名师精心整理-第 8 页,共 23 页 -mov ds,
10、ax;程序的主要部分mov ax,nmov array_head-2,0ffffh ;-1送array_head-2 单元mov si,0compare:cmp array_endsi,axjle insertmov bx,array_endsimov array_endsi+2,bxsub si,2jmp short compareinsert:mov array_endsi+2,axretmain endp ;主程序 main结束prognam endsend start例5.5 设有数组 X(X1,X10)和Y(Y1,Y10),编程计算数组 Z(Z1,名师资料总结-精品资料欢迎下载-名师
11、精心整理-第 9 页,共 23 页 -,Z10),其中: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名师资料总结-精品资料欢迎下载-名师精心整理-第 10 页,共 23 页 -;定义数据段 datarea segmentx dw x1,x2,x3,x4,x5,x6.x7,x8,x9,x10y dw y1,y2,y3,y4,y5,y6,y7,y8,y9,y10z dw z1,z2,z3,z4,z5,z6,z7,z8,z9,z10logic_rule dw 0
12、0dchdatarea ends;定义代码段prognam segmentmain proc far assume cs:prognam,ds:datareastart:push ds sub ax,ax push ax mov ax,datarea mov ds,ax mov bx,0mov cx,10mov dx,logic_rulenext:mov ax,xbxshr dx,1jc subtractadd ax,ybxjmp short resultsubtract:sub ax,ybxresult:mov zbx,axadd bx,2loop nextretmain endp prog
13、nam ends名师资料总结-精品资料欢迎下载-名师精心整理-第 11 页,共 23 页 -end start这种设置逻辑尺的方法是很常用的。例如,在矩阵运算中,为了跳过操作数为0的计算,经常采用这种方法。又如,把一组数据存入存储器时,如果其中数值为0的元素很多,也可用这种方法设立一个每位表示一个下标的逻辑尺(这样的逻辑尺可能占有几个字,由数组的长度确定。),0元素就可不占有存储单元了。在例 5.5中,每个标志只占一位,如果要表示的特征数更多,则每个标志可占有几位,而在处理方法上是完全相同的。设立标志位的方法除了如逻辑尺那样可静态地预置外,还可以在程序中动态地修改标志位的值,以达到控制的目的,
14、下例将说明这种方法。例5.5 试编制一程序:从键盘输入一行字符,要求第一个键入的字符必须是空格符,如不是,则退出程序;如是,则开始接收键入的字符并顺序存放在首地址为BUFFER的缓冲区中(空格符不存入),直到接收到第二个空格符时退出程序。这一程序要求接收的字符从空格符开始又以空格符结束,因此程序中必须区分所接收的字符是否是第一个字符。为此,设立作为标志的存储单元 FLAG。一开始将其置为 0,接收第一个字符后可将其置1。整个程序的框图如图所示。名师资料总结-精品资料欢迎下载-名师精心整理-第 12 页,共 23 页 -;定义数据段datarea segmentbuffer db 80 dup(
15、?)flag db?datarea ends;定义代码段prognam segment main proc farassume cs:prognam,ds:datareastart:push dssub ax,axpush axmov ax,datareamov ds,axlea bx,buffermov flag,0next:mov ah,01名师资料总结-精品资料欢迎下载-名师精心整理-第 13 页,共 23 页 -int 21htest flag,01hjnz/jne followcmp al,20hjnz/jne exitmov flag,1jmp nextfollow:cmp al,
16、20hjz/je exitmov bx,alinc bxjmp nextexit:retmainendp prognam ends end start例5.6有一个首地址为 A的N字数组,请编制程序使该数组中的数按照从小到大的次序整序。解析:这里采用起泡排序算法实现数组整序。从第一个数开始依次对相邻两个数 Ki 和Ki+1 进行比较,若 KiKi+1,Ki 的位置不动,Ki+1 继续和 Ki+2比较;若 KiKi+1,则两者交换位置,Ki+1(交换前的 Ki)继续和 Ki+2比较。(P172页)名师资料总结-精品资料欢迎下载-名师精心整理-第 14 页,共 23 页 -(气泡算法,多重循环)3
17、2,85,16,15,8;定义数据段dseg segmentn equ 5 ;数组中数的个数a dw n dup(?)dseg ends名师资料总结-精品资料欢迎下载-名师精心整理-第 15 页,共 23 页 -;定义代码段cseg segmentmain proc farassume cs:cseg,ds:dsegstart:mov ax,dsegmov ds,axmov cx,ndec cx ;设置 count1loop1:mov di,cx ;保存 count1mov si,0 ;初始化 siloop2:mov ax,asicmp ax,asi+2 ;Ki 与Ki+1 比较jle con
18、tinue ;如果 Ki Ki+1,不交换xchg ax,asi+2mov asi,ax ;如果 Ki Ki+1,交换continue:add si,2 ;修改地址loop loop2 ;内循环mov cx,di ;恢复 count1loop loop1 ;外循环mov ax,4c00hint 21hmain endpcseg endsend start5.2 分支程序设计分支程序有两种基本结构,如图所示。名师资料总结-精品资料欢迎下载-名师精心整理-第 16 页,共 23 页 -它们分别相当于高级语言中的IF_THEN_ELSE 语句和 CASE语句,适用于要求根据不同条件作不同处理的情况。
19、IF_THEN_ELSE 语句可以引出两个分支,CASE语句则可以引出多个分支,不论哪一种形式,它们的共同特点是:运行方向是向前的,在某一种特定条件下,只能执行多个分支中的一个分支。名师资料总结-精品资料欢迎下载-名师精心整理-第 17 页,共 23 页 -cseg segmentmain proc near assume cs:cseg,ds:datastart:mov ax,dsegmov ds,ax名师资料总结-精品资料欢迎下载-名师精心整理-第 18 页,共 23 页 -exit:mov ax,4c00hint 21h名师资料总结-精品资料欢迎下载-名师精心整理-第 19 页,共 23
20、 页 -main endpcseg endsend start例:试根据 AL 寄存器中哪一位为 1(从低位到高位)把程序转移到8个不同的程序分支中去。branch_addresses segment ;定义数据段 branch_table dw routine_1 dw routine_2 dw routine_3 dw routine_4 dw routine_5 dw routine_6 dw routine_7 dw routine_8 branch_addresses endsprocedure_select segment ;定义代码段 main proc far ;定义主程序 m
21、ain assume cs:procedure_select,ds:branch_addressesstart:push ds sub bx,bx push bx mov bx,branch_addresses mov ds,bx;程序的主要部分(寄存器相对寻址)cmp al,0 ;(al)=0?je continue ;(al)为0则转到 continue_main_line mov si,0 l:shr al,1;把al逻辑右移 1位 jnc not_yet ;CF=0 转到 not_yet jmp branch_tablesi ;CF=1转到相应程序分支 not_yet:add si,t
22、ype branch_table ;修改地址 add si,2 jmp l ;无条件跳到 l 名师资料总结-精品资料欢迎下载-名师精心整理-第 20 页,共 23 页 -continue:;其它程序段 routine_1:;程序段 1 routine_2:;程序段 2 ret main endp ;主程序 main结束 procedure_select ends end start用寄存器间接寻址方式实现跳跃表法的程序如下(仅给出修改后的程序的主要部分):cmp al,0 je continue lea bx,branch_table;branch_table的偏移地址送bx l:shr al
23、,1 jnc not_yet ;CF=0转到not_yet jmp word ptrbx ;CF=1 转到相应程序分支 not_yet:add bx,type branch_table;修改地址 jmp l ;无条件跳到l continue:用基址变址寻址方式实现跳跃表法的程序如下(仅给出修改后的程序的主要部分),与前两种寻址方式的主要区别是这里使用了逻辑左移指令,即从 al 的高位向低位判断,而前两段程序是从al 的低位向高位判断。cmp al,0 je continue lea bx,branch_table mov si,7*type branch_table;14 送si mov cx
24、,8 ;循环次数名师资料总结-精品资料欢迎下载-名师精心整理-第 21 页,共 23 页 -8送cx l:shl al,1 ;把al 逻辑左移1位 jnb not_yet ;CF=0 转到not_yet jmp word ptrbxsi ;CF=1转到相应程序分支 not_yet:sub si,type branch_table;修改地址 loop l ;循环 continue:以上多个例子都是既有分支结构又有循环结构,实际上,多数程序都是各种程序结构的组合。而且,循环结构可以看作分支结构的一种特例,它只是多次走一个分支,只在满足循环结束条件时,走另一个分支罢了。【本章小结】编制一个汇编语言程
25、序的步骤如下:1)分析题意,确定算法。2)根据算法,画出程序框图。3)根据框图编写程序。4)上机调试程序。程序有顺序、循环、分支和子程序四种结构形式。循环程序有两种基本结构:一种是DO_WHILE 结构;另一种是DO_UNTIL 结构。一般由以下四个部分组成:(1)初始化部分(2)循环体(3)修改部分(4)控制部分算法和循环控制条件的选择对程序的工作效率有很大的影响,而循环控制条件的选择又是很灵活的,应该根据具体情况来确定。考虑算法时必须把可能出现的边界情况考虑在内。设置逻辑尺是循环控制中很常用的一种方法。除了静态地预置外,还可以在程序中动态地修改标志位的值,以达到控制的目的。循环可以有多层结
26、构。多重循环程序设计的基本方法和单重循环程名师资料总结-精品资料欢迎下载-名师精心整理-第 22 页,共 23 页 -序设计是一致的,应分别考虑各重循环的控制条件及其程序实现,相互之间不能混淆。另外,应该注意在每次通过外层循环再次进入内层循环时,初始条件必须重新设置。起泡排序算法是多重循环程序设计中的一种常用方法。分支程序结构可以有两种形式。分别相当于高级语言中的IF_THEN_ELSE 语句和 CASE语句,适用于要求根据不同条件作不同处理的情况。IF_THEN_ELSE 语句可以引出两个分支,CASE语句则可以引出多个分支,不论哪一种形式,它们的共同特点是:运行方向是向前的,在某一种特定条件下,只能执行多个分支中的一个分支。数组排序算法中可以采用折半查找法来提高查找效率。CASE结构可以使用跳跃表法实现,使程序能根据不同的条件转移到多个程序分支中去。跳跃表法是一种很有用的分支程序设计方法。名师资料总结-精品资料欢迎下载-名师精心整理-第 23 页,共 23 页 -