,单击此处编辑母版标题样式,*,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,第五章 循环与分支程序设计,5.1 循环程序设计,5.2 分支程序设计,5.3 如何在实模式下发挥80386及其后继机型的优势,第五章 循环与分支程序设计5.1 循环程序设计,1,1.,编写汇编语言程序步骤,l,分析实际问题,确定解决问题的算法,l,按算法画出程序流程图,l,按流程图编写程序,l,上机调试,运行程序,注:本教材所讨论的编程环境只限于,在DOS操作系统下的实模式,1.编写汇编语言程序步骤注:本教材所讨论的编程环境只限于,2,2.判断程序质量的标准,程序的正确性,程序的可读性,程序的执行时间,程序所占内存大小,2.判断程序质量的标准,3,3几种程序结构,顺序结构,循环结构,分支结构,子程序结构,3几种程序结构,4,顺序结构形式,顺序结构形式,5,循环结构形式,当型循环,(当条件成立进入循环),循环初始设置,循环体,循环条件判断?,Y,N,直到型循环,(直到条件成立退出循环),Y,N,循环初始设置,循环体,循环条件判断?,循环结构形式当型循环循环初始设置循环体循环条件判断?YN直到,6,两个分支,Y,N,、,CMP AL,BL,JG great,JMP exit,great:,exit:、,、,AL,BL处理,AL,BL处理,分支结构形式,两个分支YN 、ALBL处理ALBL处,7,三个分支,、,CMP AL,0,JG great,JL less,JMP exit,less:,JMP exit,great:,exit:,、,AL,=,0处理,AL0处理,AL0处理AL,8,1多处调用完成同一功能的子程:,code SEGMENT,start:、,CALL subp,、,CALL subp,、,CALL subp,、,MOV AH,4CH,INT 21H,subp PROC,、,、,RET,subp ENDP,code ENDS,END start,2模块化程序设计:,code SEGMENT,begin:,CALL,sub1,CALL sub2,CALL sub3,MOV AH,4CH,INT 21H,sub1 PROC,、,RET,sub1 ENDP,sub2 PROC,、,RET,sub2 ENDP,sub3 PROC,、,RET,sub3 ENDP,code ENDS,END begin,子程结构形式,注意返回,DOS,语句位置,1多处调用完成同一功能的子程:2模块化程序设计:子程结构,9,开,始,结,束,初,始,化 循环的初始状态,循,环,体 循环的工作部分及修改部分,控制条件,计数控制,特征值控制,地址边界控制,5.1.1 循环程序的结构形式,5.1 循环程序设计,(1)DO-WHILE,结构 (2)DO-UNTIL结构,开 始结 束 初 始 化,10,有关字符、数码转换的处理,1.计算机处理字符时,常用的字符编码是ASCII 码。,2.数字和字母的ASCII码是一个有序序列,数字09 :,30,H 39H,大写字母AZ:,41,H 5AH,小写字母az :,61,H 7AH,5.1.2 循环程序设计方法,例5.1,将寄存器BX中的内容以十六进制形式显示出来。,有关字符、数码转换的处理5.1.2 循环程序设计方法例5.,11,BX是一个16位寄存器,二进制 1010 1001 0011 1110,用十六进显示时,每4位用一个字符显示,共4个,其中:,0000,0,30H,,,1010,A,41H,0001,1,31H,,,1011,B,42H,、,1001,9,39H,,,1111,F,46H,?,十六进制 A 9 3 E,屏幕上的显示 A 9 3 E,对应的ASCII 41H 39H 33H 45H,BX是一个16位寄存器 用十六进显示时,每4位用一个字符显,12,BX,1,2,3,4,BX1,13,算法:,取出要显示的某4位,转换为对应的ASCII码,再调用DOS系统功能进行显示。,(1),对于00001001(09),先扩展成一个字节,高4位清0,,加上30H后,即可得字符09对应的ASCII码。,0000 0001B+30H=31H 0000 1001B+30H=39H,0001,B 1,1001,B 9,(2),对于10101111(AF),先扩展成一个字节,高4位清0,,加上30H后,还要再加上07H,才能得到AF 对应的ASCII码,0000 1010B+30H+,07H,=41H 0000 1111B+30H+,07H,=46H,1010,B A,1111,B F,算法:(1)对于00001001(09),先扩展,14,code SEGMENT,ASSUME CS:code,start:,MOV CH,4,;字符个数,rotate:MOV CL,4,;循环移位次数,ROL BX,CL,;取显示位的值,MOV AL,BL,;保存在AL中,AND AL,0FH,;清除高4位,ADD AL,30H,;转变为数字的ASCII,CMP AL,3aH,;,大于3aH,则应转变,JL print,;,为数字09的ASCII,ADD AL,07H,;,为字母AF的ASCII,print:MOV DL,AL ;,送,ASCII字符到DL,MOV AH,2 ;,显示DL中的字符,INT 21H,DEC CH,;显示结束?,JNZ next,MOV AH,4CH,;返回DOS,INT 21H,code ENDS,END start,显示字符个数CH=4,循环移位次数CL=4,BX循环左移4位,将要显示的值移至低4位,保存在AL中,清AL 的高4位,,只保留要显示位的值,AL AL+30H,完成数值09的ASCII码转换,Y,N,ALAL+07H,完成数值AF的ASCII码转换,用02功能显示DL中的字符,Y,N,返回DOS,AL 超出39H?,CH CH-1转换结束?,开始,code SEGMENT显示字符个数CH=4BX循环左,15,例5.2,在ADDR单元中存放着数,度编制一程序把中1的个数存入COUNT单元中。,datarea segment,addre dw 1234h,count dw?,datarea ends,mov cx,0,mov bx,addre,mov ax,bx,again:test ax,0ffffh,jz exit,jns shift,inc cx,shift:shl ax,1,jmp again,exit:mov count,cx,ret,例5.2 在ADDR单元中存放着数,度编制一程序把中1,16,例5.4,将,正数,n插入一个,已整序,的字数组的正确位置。,x dw?,array_head dw 3,5,15,23,37,49,52,65,78,99,array_end dw 105,n dw 32,mov ax,n,mov array_head-2,0ffffh,mov si,0,compare:,cmp array_endsi,ax,jle insert,mov bx,array_endsi,mov array_endsi+2,bx,sub si,2,jmp short compare,insert:,mov array_endsi+2,ax,-1,3,5,49,15,52,23,37,105,99,78,65,32,x,n,例5.4 将正数n插入一个已整序的字数组的正确位置。,17,例 5.5 ,i,=X,i,+Y,i,LOGIC_RULE,DW00DCH,MOVBX,0,MOVCX,10,MOV,DX,LOGIC_RULE,NEXT:MOVAX,XBX,SHRDX,1,JC,SUBTRACT,ADDAX,YBX,JMPSHORT RESULT,SUBTRACT:,SUBAX,YBX,RESULT:,MOVZBX,AX,ADDBX,2,LOOPNEXT,RET,例 5.5 i=Xi+YiLOGIC_RULEDW,18,例5.6,键入一行以空格开头以空格结束的字符串,datarea segment,bufferdb 80 dup(?),flagdb?,datarea ends,lea bx,buffer,mov flag,0,next:mov ah,01,;读键盘,int 21h ;,所读内容放入al,test flag,01h ;,flag=1?,jnz follow ;,flag=0,zf=1不转,cmp al,20h,;al是空格,?,jnz exit,;不是,zf=0退出,mov flag,1,;置标志flag=1,jmp next,follow:cmp al,20h,;al是空格?,jz exit,;是,zf=1,退出,mov bx,al,;不是,保存,inc bx,;数组索引加1,jmp next,exit:,20,a,b,c,d,e,f,20,flag=0 1 jz exit成立,例5.6 键入一行以空格开头以空格结束的字符串datare,19,5.1.3 多重循环程序设计,基本方法与单重循环相同,但要注意:,1、,分别考虑各重循环的控制条件及其程序实现,相互之间不能混淆,2、每次从外层循环再次进入内层循环时,初始条件要重新设置,5.1.3 多重循环程序设计基本方法与单重循环相同,但要注意,20,例5.7,将首地址为a的字数组从大到小排序(气泡算法,多重循环),a dw 100,30,78,99,15,-1,66,54,189,256,mov cx,10,;待排序数的个数,dec cx,;外循环的次数,loop1,:,mov di,cx,;暂存外循环次数,mov bx,0,;数组下标,loop2,:,mov ax,abx,;取第bx个数,cmp ax,abx+2,;与后一个数比较,jge continue,;bx=bx+2,xchg ax,abx+2,;=,转移,不换,xchg es:di+2,ax,mov es:di,ax,sub bx,bx,;,排序标志,cont:loop next,cmp bx,0,;bx=1,已排好,je init,sorted:,mov di,start_addr,例5.8 附加段字数组首地址存于DI,第1字存放长度,从小到,22,练习5.11:从键盘输入一系列以$结束的字符串,统计数字字符的个数,data segment,count dw 0,buff db 50 dup(?),data ends,prognam segment,main proc far,assume cs:prognam,start:,push ds,sub ax,ax,push ax,mov ax,data,mov ds,ax,lea bx,buff,;取缓冲地址,input:mov ah,01,;从键盘读串,int 21H,;存入al中,mov bx,al,;保存字符,inc bx,;buff数组下标,cmp al,$,;是不是$,jnz input,;是,结束读,lea bx,buff,;取串地址,mov ax,0,next:mov cl,bx,;取串中字符,inc bx,;指向下一字符,cmp cl,$,;是不是$,jz disp,;是,zf=1,转移,cmp cl,30h,;与0比较,jb cont,;9,不计数,inc ax,;计数,cont:jmp next,disp:ret,main endp,prognam ends,end start,练习5.11:从键盘输入一系列以$结束的字符串,统计数字字符,23,练习5.11:测试一字符串是否存在数字,若存在,置CL第5位置1,否则置0,data segment,string db abcqdefghijklmnopqrs,data ends,prognamsegment,main proc far,assume cs:prognam,ds:data,es:data,start:push ds,s