1、第五章第五章 循环与分支程序设计循环与分支程序设计 1.编写汇编语言程序步骤编写汇编语言程序步骤 l l 分析实际问题,确定解决问题的算法分析实际问题,确定解决问题的算法 l l 按算法画出程序流程图按算法画出程序流程图 l l 按流程图编写程序按流程图编写程序 l l上机调试上机调试,运行程序运行程序 注:本教材所讨论的编程环境只限于注:本教材所讨论的编程环境只限于 在在DOSDOS操作系统下的实模式操作系统下的实模式2.判断程序质量的标准判断程序质量的标准l 程序的正确性程序的正确性l 程序的可读性程序的可读性l 程序的执行时间程序的执行时间l 程序所占内存大小程序所占内存大小3几种程序结
2、构几种程序结构l 顺序结构顺序结构l 循环结构循环结构l 分支结构分支结构l子程序结构子程序结构顺序结构形式顺序结构形式循环结构形式循环结构形式当型循环当型循环(当条件成立进入循环当条件成立进入循环)循环初始设置循环初始设置循环体循环体循环条件判断循环条件判断?YN直到型循环直到型循环(直到条件成立退出循环直到条件成立退出循环)YN循环初始设置循环初始设置循环体循环体循环条件判断循环条件判断?两个分支两个分支YN 、CMP AL,BL JG great JMP exitgreat:exit:、ALBL处理处理AL BL处理处理分支结构形式分支结构形式三个分支三个分支 、CMP AL,0 JG
3、great JL less JMP exitless:JMP exitgreat:exit:、AL=0处理处理AL0处理处理AL=bx+2=bx+2 xchg xchg ax,abx+2 ax,abx+2 ;=,转移转移,不换不换xchg es:di+2,axmov es:di,axsub bx,bx ;排序标志排序标志cont:loop nextcmp bx,0 ;bx=1,已排好已排好je initsorted:mov di,start_addr练习5.11:从键盘输入一系列以$结束的字符串,统计数字字符的个数data segmentcount dw 0buff db 50 dup(?)d
4、ata endsprognam segmentmain proc farassume cs:prognamstart:push dssub ax,axpush axmov ax,datamov ds,axlea bx,buff ;取缓冲地址input:mov ah,01 ;从键盘读串int 21H ;存入al中mov bx,al ;保存字符inc bx ;buff数组下标cmp al,$;是不是$jnz input ;是,结束读lea bx,buff ;取串地址mov ax,0next:mov cl,bx;取串中字符inc bx;指向下一字符cmp cl,$;是不是$jz disp ;是,zf
5、=1,转移cmp cl,30h;与0比较jb cont ;9,不计数inc ax ;计数cont:jmp nextdisp:retmain endpprognam endsend start练习5.11:测试一字符串是否存在数字,若存在,置CL第5位置1,否则置0data segmentstring db abcqdefghijklmnopqrsdata endsprognamsegmentmain proc farassume cs:prognam,ds:data,es:datastart:push dssub ax,axpush axmov ax,datamov ds,axmov es,a
6、xbegin:mov cx,20 ;字符个数mov si,0 ;数组下标again:mov al,stringsicmp al,30h ;与0比较jb goon ;,转移or cl,20h ;有数字,置5位jmp exitgoon:inc si ;数组下标加1loop againand cl,0dfh ;无数字,清5位exit:retmain endpprognam endsend start循环程序设计小结循环程序设计小结1 1、循环控制条件的选择:、循环控制条件的选择:a.a.循环次数已知,采用循环次数已知,采用LOOPLOOPb.b.循环次数已知,但有可能使用其他特征或条件结束循环,循环
7、次数已知,但有可能使用其他特征或条件结束循环,可采用可采用LOOPZLOOPZ和和LOOPNZLOOPNZc.c.循环次数未知,具体问题具体分析循环次数未知,具体问题具体分析2 2、设立条件标志位的方法设立条件标志位的方法5.2 分支程序设计分支程序设计5.2.1分支程序的结构形式分支程序的结构形式双分支与多分支的共同特点:双分支与多分支的共同特点:运行方向是向前的在某一种特定条件下,只能执行其中的一个分支5.2.1分支程序设计方法分支程序设计方法1 1、使用、使用CMPCMP、TESTTEST等运算型指令等运算型指令+条件转移指令条件转移指令2 2、使用逻辑尺的方法、使用逻辑尺的方法3 3、
8、使用跳跃表法实现、使用跳跃表法实现CASECASE结构结构例例5.9 折半查找:附加段有一个有序字数组,首字表示数折半查找:附加段有一个有序字数组,首字表示数组长度,组长度,AX是待查字,若找到是待查字,若找到CF=0,否则否则CF=1dseg segmentlow_idxdw?high_idxdw?listdw12,11,22,33,44,55,66,77,88,99,111,222,333targetdw77dseg endscseg segmentmain proc farassume cs:cseg,ds:dseg,es:dsegstart:push dssub ax,axpush a
9、xmov ax,dsegmov ds,axmov es,ax例例5.9 折半查找:附加段有一个有序字数组,首字表示折半查找:附加段有一个有序字数组,首字表示数组长度,数组长度,AX是待查字,若找到是待查字,若找到CF=0,否则否则CF=1mov ax,target;lea di,list;取数组首地址cmp ax,es:di+2;取第1个数ja chk_last;第1个,检查最后1个lea si,es:di+2;=第1个je exit;,退出stc;CF=1,没找到jmp exitchk_last:mov si,es:di;下面三条使SI指向shl si,1;数组末元素add si,dicmp
10、 ax,es:si;与末元素比较jb search;,头到末之后add cx,dx;以下三条计算shr cx,1;头与末的中点mov si,cxshl si,1;对准中间字0500100102104106108list10A(1+5)/2=3 3*2=6 DI偏移6,即106,即第3字compare:cmp ax,es:bx+si;比较,bx指向数组首元素je exit;,找到,退出ja highter;,调节搜索头dec cx;=mov high_idx,cx;调节搜索末jmp midhighter:inc cxmov low_idx,cx;调节搜索头jmp midno_match:stce
11、xit:ret例例5.9 折半查找:附加段有一个有序字数组,首字折半查找:附加段有一个有序字数组,首字表示数组长度,表示数组长度,AX是待查字,若找到是待查字,若找到CF=0,否则否则CF=1例例5.10 根据根据AL寄存器中哪一位为寄存器中哪一位为1(从低位到高位)把程序(从低位到高位)把程序 转移到转移到8个不同的程序分支去个不同的程序分支去。branch_table branch_table dwdw routine1 routine1 dwdw routine2 routine2 dwdw routine3 routine3 dwdw routine4 routine4 dwdw ro
12、utine5 routine5 dwdw routine6 routine6 dwdw routine7 routine7 dwdw routine8 routine8注意:注意:DW 标号的使用标号的使用寄存器间接寻址寄存器间接寻址 cmpcmp al,0 al,0 je je continue continue lea bx lea bx,branch_table,branch_tableL L :shr:shr al,1 al,1 ;逻辑右移,最低位进入逻辑右移,最低位进入CFCF位位 jnb not_yet jnb not_yet ;jnb=jnc,CFjnb=jnc,CF=0,=0,
13、转移转移 jmp word ptrjmp word ptr bxbx ;段内间接转移段内间接转移not_yet:not_yet:add bx add bx,type branch_table,type branch_table jmp jmp L Lcontinuecontinue:routine1:routine1:routine2:routine2:调试源程序变址寻址方式实现变址寻址方式实现 cmpcmp al,0 al,0 je je continue continue mov si mov si,0,0 L L :shr:shr al,1 al,1 ;逻辑右移逻辑右移,最低位进入最低位
14、进入CFCF位位 jnb not_yetjnb not_yet;jnb=jnc,CF;jnb=jnc,CF=0,=0,转移转移 jmpjmp branch_tablesibranch_tablesi ;段内间接转移段内间接转移not_yetnot_yet:add siadd si,type branch_table,type branch_table jmp jmp L Lcontinuecontinue:routine1:routine1:routine2:routine2:调试源程序基址变址寻址基址变址寻址 cmpcmp al,0 al,0 je je continue continue
15、lea bx lea bx,branch_table,branch_table mov si mov si,7,7*type branch_table type branch_table mov cx mov cx,8,8L L :shl al,1 :shl al,1 ;逻辑左移,最高位进入逻辑左移,最高位进入CFCF位位 jnb not_yetjnb not_yet;jnb=jnc,CFjnb=jnc,CF=0,=0,转移转移 jmp word ptrjmp word ptr bxsibxsi;段内间接转移段内间接转移not_yetnot_yet:sub sisub si,type bran
16、ch_table,type branch_table loop loop L Lcontinuecontinue:routine1:routine1:routine2:routine2:调试源程序习题习题5.21 试写一程序,要求比较数组试写一程序,要求比较数组ARRAY中的三个中的三个16位补码数,并根据比较结果在终端上显示如下信息:位补码数,并根据比较结果在终端上显示如下信息:(1)如果三个数都不相等,则显示如果三个数都不相等,则显示0(2)如果有两个相等则显示如果有两个相等则显示1(3)如果都相等,则显示如果都相等,则显示2dseg segmentarray dw 3 dup(?)dse
17、g endscseg segmentmov cx,3lea si,arraybegin:push cxmov cl,4mov di,4mov dl,mov ah,02int 21hinput:mov ah,01hint 21hand al,0fhshl dx,clor dl,aldec dijne inputmov si,dxadd si,2pop cxloop begincompa:lea si,arraymov dx,0mov ax,simov bx,si+2cmp ax,bxjne next1inc dxnext1:cmp si+4,axjne next2inc dxnext2:cmp
18、si+4,bxjne numinc dxnum:cmp dx,3jl dispdec dxdisp:mov ah,2add dl,30hint 21hmain endpcseg endsend start习题习题5.23 已定义整型变量、已定义整型变量、(1)若只有一个奇数,奇数存入,偶数存入若只有一个奇数,奇数存入,偶数存入(2)若两个奇数,若两个奇数,A=A+1 B=B+1(3)若两个偶数若两个偶数,A、值不变、值不变begin:mov ax,amov bx,bxor ax,bxtest ax,1hjz class ;同奇同偶,转移text bx,1hjz exitxchg bx,amov
19、 b,bxjmp exitclass:test bx,1hjz exit ;若同偶,退出inc b inc aexit:ret5.3 如何在实模式下发挥如何在实模式下发挥80386及其后继机型的优势及其后继机型的优势80386及其后继机型不但兼容及其后继机型不但兼容8086的程序,运行速度更快;的程序,运行速度更快;而且还有其它的一些优势:而且还有其它的一些优势:5.3.1 充分利用高档机的充分利用高档机的32位字长特征位字长特征5.3.2 通用寄存器可作为指针寄存器通用寄存器可作为指针寄存器5.3.3与与比例因子比例因子有关的寻址方式有关的寻址方式调试源程序例5.11通用寄存器作指针寄存器通
20、用寄存器作指针寄存器8个个32位通用寄存器都可以作为基址或变址寄存器使位通用寄存器都可以作为基址或变址寄存器使用,但注意它们的高用,但注意它们的高16位应为位应为0。3232位字长特征位字长特征计算机一次能够处理计算机一次能够处理32位的数据,可以访问位的数据,可以访问32位的位的8个通用寄存器,但个通用寄存器,但EIP和和EFLAGS在实模式下只有低在实模式下只有低16位可以使用。位可以使用。比例因子比例因子方便了表格处理和多位数组处理方便了表格处理和多位数组处理实实模模式式段段的的大大小小限限于于64K实模式下的程序是一种混合的实模式下的程序是一种混合的16位和位和32位代码位代码纯16位模块(1)所有段长都小于64KB;(2)数据项主要是8位或16位的(3)指向代码或数据的指针只 有16位偏移地址(4)只有16位段之间传送控制纯32模块(1)段长可大于64KB(04GB);(2)数据项主要是8位或32位的(3)指向代码或数据的指针 有32位偏移地址(4)只有32位段之间传送控制8086/80286实模式80386+保护模式386+实模式下的程序(1)在同一模块中,允许同时使用16位和32位的操作数和寻址方式(2)段必须实16位的,但段中的指令可以是混合的16位和32位代码奔腾4第五章作业第五章作业Page 1931955.10 5.21