您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > IBM-PC汇编语言程序设计5
第五章循环与分支程序设计5.1循环程序设计5.2分支程序设计5.3如何在实模式下发挥80386及其后继机型的优势1.编写汇编语言程序步骤l分析实际问题,确定解决问题的算法l按算法画出程序流程图l按流程图编写程序l上机调试,运行程序注:本教材所讨论的编程环境只限于在DOS操作系统下的实模式2.判断程序质量的标准l程序的正确性l程序的可读性l程序的执行时间l程序所占内存大小3.几种程序结构l顺序结构l循环结构l分支结构l子程序结构顺序结构形式循环结构形式当型循环(当条件成立进入循环)循环初始设置循环体循环条件判断?YN直到型循环(直到条件成立退出循环)YN循环初始设置循环体循环条件判断?两个分支YN、、、CMPAL,BLJGgreatJMPexitgreat:exit:、、、、、、AL≤BL处理ALBL处理分支结构形式三个分支、、、CMPAL,0JGgreatJLlessJMPexitless:JMPexitgreat:exit:、、、AL=0处理AL0处理AL0处理YYNN分支结构形式……1.多处调用完成同一功能的子程:codeSEGMENTstart:、、CALLsubp、、CALLsubp、、CALLsubp、、MOVAH,4CHINT21HsubpPROC、、、、RETsubpENDPcodeENDSENDstart2.模块化程序设计:codeSEGMENTbegin:CALLsub1CALLsub2CALLsub3MOVAH,4CHINT21Hsub1PROC、、RETsub1ENDPsub2PROC、、RETsub2ENDPsub3PROC、、RETsub3ENDPcodeENDSENDbegin子程结构形式注意返回DOS语句位置开始结束初始化循环的初始状态循环体循环的工作部分及修改部分控制条件计数控制特征值控制地址边界控制5.1.1循环程序的结构形式5.1循环程序设计(1)DO-WHILE结构(2)DO-UNTIL结构▲有关字符、数码转换的处理1.计算机处理字符时,常用的字符编码是ASCII码。2.数字和字母的ASCII码是一个有序序列数字0~9:30H~39H大写字母A~Z:41H~5AH小写字母a~z:61H~7AH5.1.2循环程序设计方法例5.1将寄存器BX中的内容以十六进制形式显示出来。▲BX是一个16位寄存器二进制1010100100111110▲用十六进显示时,每4位用一个字符显示,共4个其中:0000→’0’30H,1010→’A’41H0001→’1’31H,1011→’B’42H、、、、1001→’9’39H,1111→’F’46H?十六进制A93E屏幕上的显示‘A’‘9’‘3’‘E’对应的ASCII41H39H33H45HBX1234算法:取出要显示的某4位,转换为对应的ASCII码,再调用DOS系统功能进行显示。(1)对于0000~1001(0~9),先扩展成一个字节,高4位清0,加上30H后,即可得字符’0’~’9’对应的ASCII码。00000001B+30H=31H00001001B+30H=39H0001B‘1’1001B‘9’(2)对于1010~1111(A~F),先扩展成一个字节,高4位清0,加上30H后,还要再加上07H,才能得到’A’~’F’对应的ASCII码00001010B+30H+07H=41H00001111B+30H+07H=46H1010B‘A’1111B‘F’codeSEGMENTASSUMECS:codestart:MOVCH,4;字符个数rotate:MOVCL,4;循环移位次数ROLBX,CL;取显示位的值MOVAL,BL;保存在AL中ANDAL,0FH;清除高4位ADDAL,30H;转变为数字的ASCIICMPAL,3aH;大于3aH,则应转变JLprint;为数字0~9的ASCIIADDAL,07H;为字母A~F的ASCIIprint:MOVDL,AL;送ASCII字符到DLMOVAH,2;显示DL中的字符INT21HDECCH;显示结束?JNZnextMOVAH,4CH;返回DOSINT21HcodeENDSENDstart显示字符个数CH=4循环移位次数CL=4BX循环左移4位,将要显示的值移至低4位,保存在AL中清AL的高4位,只保留要显示位的值AL←AL+30H完成数值0~9的ASCII码转换YNAL←AL+07H完成数值A~F的ASCII码转换用02功能显示DL中的字符YN返回DOSAL超出39H?CH←CH-1转换结束?开始例5.2在ADDR单元中存放着数Y,度编制一程序把Y中1的个数存入COUNT单元中。datareasegmentaddredw1234hcountdw?datareaendsmovcx,0movbx,addremovax,bxagain:testax,0ffffhjzexitjnsshiftinccxshift:shlax,1jmpagainexit:movcount,cxret例5.4将正数n插入一个已整序的字数组的正确位置。xdw?array_headdw3,5,15,23,37,49,52,65,78,99array_enddw105ndw32movax,nmovarray_head-2,0ffffhmovsi,0compare:cmparray_end[si],axjleinsertmovbx,array_end[si]movarray_end[si+2],bxsubsi,2jmpshortcompareinsert:movarray_end[si+2],ax-135491552233710599786532xn例5.5Zi=Xi+YiLOGIC_RULEDW00DCH……MOVBX,0MOVCX,10MOVDX,LOGIC_RULENEXT:MOVAX,X[BX]SHRDX,1JCSUBTRACTADDAX,Y[BX]JMPSHORTRESULTSUBTRACT:SUBAX,Y[BX]RESULT:MOVZ[BX],AXADDBX,2LOOPNEXTRET……例5.6键入一行以空格开头以空格结束的字符串datareasegmentbufferdb80dup(?)flagdb?datareaendsleabx,buffermovflag,0next:movah,01;读键盘int21h;所读内容放入altestflag,01h;flag=1?jnzfollow;flag=0,zf=1不转cmpal,20h;al是空格?jnzexit;不是,zf=0退出movflag,1;置标志flag=1jmpnextfollow:cmpal,20h;al是空格?jzexit;是,zf=1,退出mov[bx],al;不是,保存incbx;数组索引加1jmpnextexit:20abcdef20flag=01jzexit成立5.1.3多重循环程序设计基本方法与单重循环相同,但要注意:1、分别考虑各重循环的控制条件及其程序实现,相互之间不能混淆2、每次从外层循环再次进入内层循环时,初始条件要重新设置例5.7将首地址为a的字数组从大到小排序(气泡算法,多重循环)adw100,30,78,99,15,-1,66,54,189,256movcx,10;待排序数的个数deccx;外循环的次数loop1:movdi,cx;暂存外循环次数movbx,0;数组下标loop2:movax,a[bx];取第bx个数cmpax,a[bx+2];与后一个数比较jgecontinue;[bx]=[bx+2]xchgax,a[bx+2];,则交换位置mova[bx],axcontinue:addbx,2;指向下一个数looploop2movcx,di;恢复外循环次数looploop1例5.8附加段字数组首地址存于DI,第1字存放长度,从小到大排序extrasegmentadw10,10h,12h,32h,21h,11h,56h,43h,33h,3h,67hextraendsdatasegmentstart_addrdw?save_cntdw?dataendsleadi,a;取有效地址movstart_addr,dimovcx,es:[di];取长度movsave_cnt,cx;数组长度init:movbx,1;结束标志decsave_cntjzsorted;zf=1,转移movcx,save_cntmovdi,start_addrnext:adddi,2movax,es:[di];取数cmpes:[di+2],ax;比较jaecont;=,转移,不换xchges:[di+2],axmoves:[di],axsubbx,bx;排序标志cont:loopnextcmpbx,0;bx=1,已排好jeinitsorted:movdi,start_addr练习5.11:从键盘输入一系列以$结束的字符串,统计数字字符的个数datasegmentcountdw0buffdb50dup(?)dataendsprognamsegmentmainprocfarassumecs:prognamstart:pushdssubax,axpushaxmovax,datamovds,axleabx,buff;取缓冲地址input:movah,01;从键盘读串int21H;存入al中mov[bx],al;保存字符incbx;buff数组下标cmpal,‘$‘;是不是$jnzinput;是,结束读leabx,buff;取串地址movax,0next:movcl,[bx];取串中字符incbx;指向下一字符cmpcl,‘$’;是不是$jzdisp;是,zf=1,转移cmpcl,30h;与’0’比较jbcont;‘0’,不计数cmpcl,39h;与’9’比较jnbenext;’9’,不计数incax;计数cont:jmpnextdisp:retmainendpprognamendsendstart练习5.11:测试一字符串是否存在数字,若存在,置CL第5位置1,否则置0datasegmentstringdb'abcqdefghijklmnopqrs'dataendsprognamsegmentmainprocfarassumecs:prognam,ds:data,es:datastart:pushdssubax,axpushaxmovax,datamovds,axmoves,axbegin:movcx,20;字符个数movsi,0;数组下标again:moval,string[si]cmpal,30h;与’0’比较jbgoon;,转移cmpal,39h;与‘9’比较jagoon;,转移orcl,20h;有数字,置5位jmpexitgoon:incsi;数组下标加1loopagainandcl,0dfh;无数字,清5位exit:retmainendpprognamendsendstart循环程序设计小结1、循环控制条件的选择:a.循环次数已知,采用LOOPb.循环次数已知,但有可能使用其他特征或条件结束循环,可采用LOOPZ和LOOPNZc.循环次数未知,具体问题具体分析2、设立条件标志位的方法5.2分支程序设计5.2.1分支程序的结构形式双分支与多分支的共同特点:运行方向是向前的在某一种特定条件下,只能执行其中的一个分支5.2.1分支程序设计方法1、使用CMP、TEST等运算型指令+条件转移指令2、使用逻辑尺的方法3、使用跳跃表法实现CASE结构例5.9折半查找:附加段有一个有序字数组,首字表示数组长度,AX是待查字,若找到CF=0,否则CF=1dsegsegmentlow_idxdw?high_idxdw?listdw12,11,22,33,44,55,66,77,88,99,111,222,333targetdw77dsegendscsegsegmentmainprocfarassumecs:cseg,ds:dseg,es:dsegstart:pus
本文标题:IBM-PC汇编语言程序设计5
链接地址:https://www.777doc.com/doc-3163964 .html