您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 第5章汇编语言循环与分支程序设计
第1页第5章循环与分支程序设计【课前思考】1.编制一个汇编语言程序分哪几步?2.循环程序有哪两种基本结构?由几部分组成?3.设计算法时对可能出现的边界情况如何考虑?4.如何设置逻辑尺?5.什么是起泡排序算法?6.如何理解数组排序算法中采用的折半查找法?7.如何使用跳跃表法实现CASE结构?【学习目标】了解并掌握循环程序的构造方法,尤其是对循环控制条件的设置以及可能出现的边界情况的考虑。掌握起泡排序算法这种多重循环程序设计中的常用方法。交换标志位的设置在此算法中更能提高效率。学会在数组排序算法中采用折半查找法来提高查找效率。学会使用跳跃表法实现CASE结构。【学习指南】掌握编程的四个步骤至关重要。通过多看举例,学会正确分析理解题意、选择合适的数据结构及算法、坚持先画框图、选取有效指令编程、最后应当掌握运用调试手段进行调试。学习多重循环程序设计前应熟练掌握单层循环程序设计的各种实现方法及实现细节,如对可能出现的边界情况的处理等。学习起泡排序算法、折半查找法、跳跃表法之前,应首先理解传统实现方法。【难重点】循环控制条件的选择。考虑循环算法时注意可能出现的边界情况。静态地预置逻辑尺。动态地修改标志位。多重循环程序设计时应分别考虑各重循环的控制条件及其程序实现,相互之间不能混淆。另外,应该注意在每次通过外层循环再次进入内层循环时,初始条件必须重新设置。起泡排序算法是多重循环程序设计中的一种常用方法。数组排序算法中可以采用折半查找法来提高查找效率。CASE结构可以使用跳跃表法实现。【知识点】编制一个汇编语言程序的一般步骤5.1循环程序设计5.1.1循环程序的基本结构5.1.2循环程序设计方法举例循环控制条件边界情况的处理逻辑尺5.1.3多重循环程序设计举例起泡排序算法交换标志位5.2分支程序设计5.2.1分支程序的基本结构5.2.2分支程序设计方法举例——折半查找法5.2.3跳跃表法第2页一般说来,编制一个汇编语言程序的步骤如下:1)分析题意,确定算法。2)根据算法,画出程序框图。3)根据框图编写程序。4)上机调试程序。程序有顺序、循环、分支和子程序四种结构形式。顺序程序结构是指完全按顺序逐条执行的指令序列,这在程序段中是大量存在的,但作为完整的程序则很少见,我们不对它们作专门讨论。5.1循环程序设计5.1.1循环程序的结构形式及组成循环程序可以有两种结构形式,如图所示。一种是DO_WHILE结构形式;另一种是DO_UNTIL结构形式。初始化:设置循环的初始状态;循环体:循环的工作部分及修改部分;控制条件:计数控制、特征值控制、地址边界控制。例5.1试编制一个程序,把BX寄存器中的二进制数以十六进制的形式显示在屏幕上。解析:根据题目要求应将BX中的内容从左到右每4位一组显示出来,共显示4个十六进制数位。如果显示的数位是0~9,则把4位二进制数加上30H,转换成相应的ASCII码30H~39H;如果是A~F,则应加上37H(30H+7),转换成ASCII码41H~46H。显示字符可以使用DOS功能调用来实现。右图是程序框图(P162页)。以binihex.asm为文件名,建立源程序如下:;binihex.asmprognamsegment;定义代码段mainprocfarassumecs:prognamstart:;程序从此处开始执行;为正常返回DOS而设置堆栈pushds第3页subax,axpushax;下面是程序的主要部分movch,4;4组二进制数rotate:movcl,4;每组4个二进制位rolbx,cl;把bx循环左移4位moval,bl;暂存bl到al中andal,0fh;仅保留al的低4位addal,30h;转换成ASCII码cmpal,3ah;要显示的数大于9?jlprintit;如果数在0~9之间则显示addal,7h;数在A~F之间则调整printit:movdl,al;把要显示字符的ASCII码送dlmovah,2;功能号2送ahint21h;DOS功能调用decch;(ch)-1jnzrotate;4组都处理完?否,循环处理下一组ret;返回DOSmainendp;主程序main结束prognamends;代码段结束endstart;结束汇编例5.2从键盘接收十进制数并存入BXprognamsegmentmainprocfarassumecs:prognamstart:pushdssubax,axpushaxmovbx,0newchar:movah,1;键盘输入int21hsubal,30hjlexit;0退出cmpal,9jgexit;9退出cbw第4页例5.3从键盘接收十六进制数并存入BXcodesegmentassumecs:code,ds:datastart:movax,4c00hint21h;返回DOScodeendsendstart例5.4将正数N插入一个已整序的字数组的正确位置。该数组的首地址和末地址分别为ARRAY_HEAD和ARRAY_END,其中所有数均为正数且已按递增的次序排列。;定义数据段datareasegmentxdw?array_headdw23,37,49,52,65,78,99array_enddw105ndw32datareaends;定义代码段prognamsegmentmainprocfar;主程序部分assumecs:prognam,ds:datareastart:;程序从此处开始执行pushdssubax,axpushaxmovax,datareamovds,ax;程序的主要部分movax,nmovarray_head-2,0ffffh;-1送array_head-2单元第5页movsi,0compare:cmparray_end[si],axjleinsertmovbx,array_end[si]movarray_end[si+2],bxsubsi,2jmpshortcompareinsert:movarray_end[si+2],axretmainendp;主程序main结束prognamendsendstart例5.5设有数组X(X1,…,X10)和Y(Y1,…,Y10),编程计算数组Z(Z1,…,Z10),其中:Z1=X1+Y1Z2=X2+Y2Z3=X3-Y3Z4=X4-Y4Z5=X5-Y5Z6=X6+Y6Z7=X7-Y7Z8=X8-Y8Z9=X9+Y9Z10=X10+Y10;定义数据段datareasegmentxdwx1,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,z10logic_ruledw00dchdatareaends;定义代码段prognamsegmentmainprocfarassumecs:prognam,ds:datarea第6页start:pushdssubax,axpushaxmovax,datareamovds,axmovbx,0movcx,10movdx,logic_rulenext:movax,x[bx]shrdx,1jcsubtractaddax,y[bx]jmpshortresultsubtract:subax,y[bx]result:movz[bx],axaddbx,2loopnextretmainendpprognamendsendstart这种设置逻辑尺的方法是很常用的。例如,在矩阵运算中,为了跳过操作数为0的计算,经常采用这种方法。又如,把一组数据存入存储器时,如果其中数值为0的元素很多,也可用这种方法设立一个每位表示一个下标的逻辑尺(这样的逻辑尺可能占有几个字,由数组的长度确定。),0元素就可不占有存储单元了。在例5.5中,每个标志只占一位,如果要表示的特征数更多,则每个标志可占有几位,而在处理方法上是完全相同的。设立标志位的方法除了如逻辑尺那样可静态地预置外,还可以在程序中动态地修改标志位的值,以达到控制的目的,下例将说明这种方法。例5.5试编制一程序:从键盘输入一行字符,要求第一个键入的字符必须是空格符,如不是,则退出程序;如是,则开始接收键入的字符并顺序存放在首地址为BUFFER的缓冲区中(空格符不存入),直到接收到第二个空格符时退出程序。这一程序要求接收的字符从空格符开始又以空格符结束,因此程序中必须区分所接收的字符是否是第一个字符。为此,设立作为标志的存储单元FLAG。一开始将其置为0,接收第一个字符后可将其置1。整个程序的框图如图所示。第7页;定义数据段datareasegmentbufferdb80dup(?)flagdb?datareaends;定义代码段prognamsegmentmainprocfarassumecs:prognam,ds:datareastart:pushdssubax,axpushaxmovax,datareamovds,axleabx,buffermovflag,0next:movah,01int21htestflag,01hjnz/jnefollowcmpal,20hjnz/jneexitmovflag,1jmpnextfollow:cmpal,20hjz/jeexitmov[bx],alincbxjmpnextexit:retmainendpprognamendsendstart例5.6有一个首地址为A的N字数组,请编制程序使该数组中的数按照从小到大的次序整序。解析:这里采用起泡排序算法实现数组整序。从第一个数开始依次对相邻两个数Ki和Ki+1进行比较,若Ki≤Ki+1,Ki的位置不动,Ki+1继续和Ki+2比较;若Ki>Ki+1,则两者交换位置,Ki+1(交换前的Ki)继续和Ki+2比较。(P172页)第8页(气泡算法,多重循环)32,85,16,15,8;定义数据段dsegsegmentnequ5;数组中数的个数adwndup(?)dsegends;定义代码段csegsegmentmainprocfarassumecs:cseg,ds:dsegstart:movax,dsegmovds,axmovcx,ndeccx;设置count1loop1:movdi,cx;保存count1movsi,0;初始化siloop2:movax,a[si]cmpax,a[si+2];Ki与Ki+1比较jlecontinue;如果Ki≤Ki+1,不交换xchgax,a[si+2]mova[si],ax;如果Ki>Ki+1,交换continue:addsi,2;修改地址looploop2;内循环movcx,di;恢复count1looploop1;外循环movax,4c00hint21hmainendpcsegendsendstart第9页5.2分支程序设计分支程序有两种基本结构,如图所示。它们分别相当于高级语言中的IF_THEN_ELSE语句和CASE语句,适用于要求根据不同条件作不同处理的情况。IF_THEN_ELSE语句可以引出两个分支,CASE语句则可以引出多个分支,不论哪一种形式,它们的共同特点是:运行方向是向前的,在某一种特定条件下,只能执行多个分支中的一个分支。第10页csegsegmentmainprocnearassumecs:cseg,ds:datastart:movax,dsegmovds,axexit:movax,4c00hint21hmainendpcsegendsendstart第11页例:试根据AL寄存器中哪一位为1(从低位到高位)把程序转移到8个不同的程序分支中去。branch_addressessegment;定义数据段branch_tabledwroutine_1dwroutine_2dwroutine_3dwroutine_4dwroutine_5dwroutine_6dwroutine_7dwroutine_8branch_addressesendsprocedure_selectsegment;定
本文标题:第5章汇编语言循环与分支程序设计
链接地址:https://www.777doc.com/doc-2196397 .html