计算机IBM-PC汇编语言程序设计课件_第1页
计算机IBM-PC汇编语言程序设计课件_第2页
计算机IBM-PC汇编语言程序设计课件_第3页
计算机IBM-PC汇编语言程序设计课件_第4页
计算机IBM-PC汇编语言程序设计课件_第5页
已阅读5页,还剩79页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第五章循环与分支程序设计5.1循环程序设计5.2分支程序设计5.3如何在实模式下发挥80386及其后继机型的优势第五章循环与分支程序设计5.1循环程序设计1

1.编写汇编语言程序步骤l

分析实际问题,确定解决问题的算法l

按算法画出程序流程图l

按流程图编写程序l上机调试,运行程序注:本教材所讨论的编程环境只限于在DOS操作系统下的实模式

1.编写汇编语言程序步骤注:本教材所讨论的编程环境只限于22.判断程序质量的标准程序的正确性程序的可读性程序的执行时间程序所占内存大小2.判断程序质量的标准33.几种程序结构顺序结构循环结构分支结构子程序结构3.几种程序结构4顺序结构形式顺序结构形式5循环结构形式当型循环(当条件成立进入循环)循环初始设置循环体循环条件判断?YN直到型循环(直到条件成立退出循环)YN循环初始设置循环体循环条件判断?循环结构形式当型循环循环初始设置循环体循环条件判断?YN直到6两个分支YN

、、、CMPAL,BLJGgreat

JMPexitgreat:

exit:、、、、、、

AL≤BL处理AL>BL处理分支结构形式两个分支YN、、、AL≤BL处理AL>BL处7三个分支

、、、CMPAL,0

JGgreat

JLless

JMPexitless:

JMPexitgreat:

exit:、、、AL=0处理AL>0处理AL<0处理YYNN分支结构形式……三个分支、、、AL=0处理AL>0处理AL81.多处调用完成同一功能的子程:codeSEGMENTstart:、、

CALLsubp、、

CALLsubp、、

CALLsubp、、MOVAH,4CHINT21HsubpPROC、、、、RETsubpENDPcodeENDSENDstart2.模块化程序设计:codeSEGMENTbegin:CALL

sub1

CALLsub2

CALLsub3MOVAH,4CHINT21Hsub1PROC、、RETsub1ENDPsub2PROC、、RETsub2ENDPsub3PROC、、RETsub3ENDPcodeENDSENDbegin

子程结构形式注意返回DOS语句位置1.多处调用完成同一功能的子程:2.模块化程序设计:子程结构9开

始结

化循环的初始状态

体循环的工作部分及修改部分

控制条件

计数控制特征值控制地址边界控制5.1.1循环程序的结构形式5.1循环程序设计(1)DO-WHILE结构(2)DO-UNTIL结构开始结束初始化10有关字符、数码转换的处理1.计算机处理字符时,常用的字符编码是ASCII码。2.数字和字母的ASCII码是一个有序序列数字0~9:30H~39H大写字母A~Z:41H~5AH小写字母a~z:61H~7AH5.1.2循环程序设计方法例5.1将寄存器BX中的内容以十六进制形式显示出来。 有关字符、数码转换的处理5.1.2循环程序设计方法例5.11BX是一个16位寄存器二进制1010100100111110

用十六进显示时,每4位用一个字符显示,共4个其中:0000→’0’30H,1010→’A’41H

0001→’1’31H,1011→’B’42H、、、、

1001→’9’39H,1111→’F’46H?十六进制A93E屏幕上的显示‘A’‘9’‘3’‘E’对应的ASCII41H39H33H45HBX是一个16位寄存器用十六进显示时,每4位用一个字符显12BX1234BX113算法:取出要显示的某4位,转换为对应的ASCII码,再调用DOS系统功能进行显示。(1)对于0000~1001(0~9),先扩展成一个字节,高4位清0,加上30H后,即可得字符’0’~’9’对应的ASCII码。00000001B+30H=31H00001001B+30H=39H

0001B‘1’1001B‘9’(2)对于1010~1111(A~F),先扩展成一个字节,高4位清0,

加上30H后,还要再加上07H,才能得到’A’~’F’对应的ASCII码00001010B+30H+07H=41H00001111B+30H+07H=46H

1010B‘A’1111B‘F’算法:(1)对于0000~1001(0~9),先扩展14codeSEGMENTASSUMECS:codestart:MOVCH,4;字符个数rotate:MOVCL,4;循环移位次数

ROLBX,CL

;取显示位的值

MOVAL,BL

;保存在AL中

ANDAL,0FH

;清除高4位

ADDAL,30H

;转变为数字的ASCII

CMPAL,3aH;大于3aH,则应转变

JLprint;为数字0~9的ASCII

ADDAL,07H;为字母A~F的ASCIIprint:MOVDL,AL;送

ASCII字符到DLMOVAH,2;显示DL中的字符INT21HDECCH;显示结束?

JNZnextMOVAH,4CH;返回DOSINT21HcodeENDS

ENDstart显示字符个数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转换结束?开始codeSEGMENT显示字符个数CH=4BX循环左15例5.2在ADDR单元中存放着数Y,度编制一程序把Y中1的个数存入COUNT单元中。datareasegment addredw1234h countdw?datareaends movcx,0 movbx,addre movax,bxagain: testax,0ffffh jzexit jnsshift inccxshift: shlax,1 jmpagainexit: movcount,cx ret 例5.2在ADDR单元中存放着数Y,度编制一程序把Y中116例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

-1

3

5

49

15

52

23

37

105

99

78

65

32xn例5.4将正数n插入一个已整序的字数组的正确位置。17例5.5Zi=Xi+Yi

LOGIC_RULE DW 00DCH …… MOV BX,0 MOV CX,10 MOV DX,LOGIC_RULENEXT: MOV AX,X[BX]

SHR DX,1

JC SUBTRACT ADD AX,Y[BX] JMP SHORTRESULTSUBTRACT: SUB AX,Y[BX]RESULT: MOV Z[BX],AX ADD BX,2 LOOP NEXT RET ……例5.5Zi=Xi+Yi LOGIC_RULE DW 18例5.6键入一行以空格开头以空格结束的字符串datareasegment buffer db80dup(?) flag db?datareaends leabx,buffer movflag,0next: movah,01;读键盘 int21h;所读内容放入al testflag,01h;flag=1? jnzfollow;flag=0,zf=1不转 cmpal,20h;al是空格? jnzexit;不是,zf=0退出 movflag,1;置标志flag=1 jmpnextfollow: cmpal,20h;al是空格? jzexit;是,zf=1,退出 mov[bx],al;不是,保存 incbx;数组索引加1 jmpnextexit:20abcdef20flag=01jzexit成立例5.6键入一行以空格开头以空格结束的字符串datare195.1.3多重循环程序设计基本方法与单重循环相同,但要注意:1、分别考虑各重循环的控制条件及其程序实现,相互之间不能混淆2、每次从外层循环再次进入内层循环时,初始条件要重新设置5.1.3多重循环程序设计基本方法与单重循环相同,但要注意20例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;指向下一个数looploop2

movcx,di;恢复外循环次数looploop1例5.7将首地址为a的字数组从大到小排序(气泡算法,多重循21例5.8附加段字数组首地址存于DI,第1字存放长度,从小到大排序

extrasegment

adw10,10h,12h,32h,21h,11h,56h,43h,33h,3h,67h

extraendsdatasegment start_addrdw? save_cntdw?dataends leadi,a;取有效地址 movstart_addr,di movcx,es:[di];取长度 movsave_cnt,cx;数组长度init: movbx,1;结束标志 decsave_cnt jzsorted;zf=1,转移 movcx,save_cnt movdi,start_addrnext: adddi,2 movax,es:[di];取数 cmpes:[di+2],ax;比较 jaecont;>=,转移,不换 xchges:[di+2],ax moves:[di],ax subbx,bx;排序标志cont: loopnext cmpbx,0;bx=1,已排好 jeinitsorted: movdi,start_addr例5.8附加段字数组首地址存于DI,第1字存放长度,从小到22练习5.11:从键盘输入一系列以$结束的字符串,统计数字字符的个数datasegment countdw0 buffdb50dup(?)dataendsprognamsegmentmainprocfar assumecs:prognamstart: pushds subax,ax pushax movax,data movds,ax leabx,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: ret mainendpprognamends endstart练习5.11:从键盘输入一系列以$结束的字符串,统计数字字符23练习5.11:测试一字符串是否存在数字,若存在,置CL第5位置1,否则置0datasegmentstringdb'abcqdefghijklmnopqrs'dataendsprognam segmentmainprocfarassumecs: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;数组下标加1 loopagain andcl,0dfh;无数字,清5位exit: ret mainendpprognamends endstart练习5.11:测试一字符串是否存在数字,若存在,置CL第5位24循环程序设计小结1、循环控制条件的选择: a.循环次数已知,采用LOOP b.循环次数已知,但有可能使用其他特征或条件结束循环, 可采用LOOPZ和LOOPNZ c.循环次数未知,具体问题具体分析2、设立条件标志位的方法循环程序设计小结255.2分支程序设计5.2.1分支程序的结构形式双分支与多分支的共同特点:运行方向是向前的在某一种特定条件下,只能执行其中的一个分支5.2.1分支程序设计方法1、使用CMP、TEST等运算型指令+条件转移指令2、使用逻辑尺的方法3、使用跳跃表法实现CASE结构5.2分支程序设计5.2.1分支程序的结构形式双分支与26例5.9

折半查找:附加段有一个有序字数组,首字表示数组长度,AX是待查字,若找到CF=0,否则CF=1dsegsegmentlow_idxdw ?high_idxdw ?listdw12,11,22,33,44,55,66,77,88,99,111,222,333targetdw 77dsegendscsegsegmentmainprocfar assumecs:cseg,ds:dseg,es:dsegstart: pushds subax,ax pushax movax,dseg movds,ax moves,ax例5.9折半查找:附加段有一个有序字数组,首字表示数组长27例5.9

折半查找:附加段有一个有序字数组,首字表示数组长度,AX是待查字,若找到CF=0,否则CF=1 movax,target ; leadi,list;取数组首地址 cmpax,es:[di+2];取第1个数 jachk_last ;>第1个,检查最后1个 leasi,es:[di+2];<=第1个 jeexit ;=,退出 stc ;CF=1,没找到 jmpexitchk_last:movsi,es:[di] ;下面三条使SI指向

shlsi,1 ;数组末元素

addsi,di cmpax,es:[si] ;与末元素比较 jbsearch ;<,搜索数组 jeexit ;=,退出 stc ;CF=1,没找到 jmpexit0400list100102104106108例5.9折半查找:附加段有一个有序字数组,首字表示数组长28例5.9

折半查找:附加段有一个有序字数组,首字表示数组长度,AX是待查字,若找到CF=0,否则CF=1search: movlow_idx,1 ;搜索开始的地方 movbx,es:[di] ;数组长度 movhigh_idx,bx ;搜索结束的地方 movbx,di ;list地址mid: movcx,low_idx ; movdx,high_idx ;

cmpcx,dx ;比较’头’与’末’指针 jano_match ;>,’头’到’末’之后 addcx,dx ;以下三条计算 shrcx,1 ;’头’与’末’的中点 movsi,cx

shlsi,1 ;对准中间’字’0500100102104106108list10A(1+5)/2=33*2=6DI偏移6,即106,即第3字例5.9折半查找:附加段有一个有序字数组,首字表示数组长29compare: cmpax,es:[bx+si] ;比较,bx指向数组首元素 jeexit ;=,找到,退出 jahighter ;>,调节搜索’头’ deccx ;<= movhigh_idx,cx ;调节搜索’末’ jmpmidhighter: inccx movlow_idx,cx ;调节搜索’头’ jmpmidno_match: stcexit: ret例5.9

折半查找:附加段有一个有序字数组,首字表示数组长度,AX是待查字,若找到CF=0,否则CF=1compare:例5.9折半查找:附加段有一个有序字数组30例5.10

根据AL寄存器中哪一位为1(从低位到高位)把程序转移到8个不同的程序分支去。branch_tabledwroutine1

dwroutine2

dwroutine3

dwroutine4

dwroutine5

dwroutine6

dwroutine7

dwroutine8注意:DW标号的使用例5.10根据AL寄存器中哪一位为1(从低位到高位)把程31寄存器间接寻址cmpal,0jecontinueleabx,branch_tableL

:shral,1;逻辑右移,最低位进入CF位jnbnot_yet

;jnb=jnc,CF=0,转移jmpwordptr[bx]

;段内间接转移not_yet:addbx,typebranch_tablejmpLcontinue:……routine1:……routine2:…………调试源程序寄存器间接寻址cmpal,0调试源程序32变址寻址方式实现cmpal,0jecontinuemovsi,0

L

:shral,1 ;逻辑右移,最低位进入CF位jnbnot_yet

;jnb=jnc,CF=0,转移jmpbranch_table[si]

;段内间接转移not_yet:addsi,typebranch_tablejmpLcontinue:……routine1:……routine2:…………调试源程序变址寻址方式实现cmpal,0调试源程序33基址变址寻址cmpal,0jecontinueleabx,branch_tablemovsi,7*typebranch_tablemovcx,8L

:shlal,1 ;逻辑左移,最高位进入CF位jnbnot_yet

;jnb=jnc,CF=0,转移jmpwordptr[bx][si]

;段内间接转移not_yet

:

subsi,typebranch_tableloopLcontinue:……routine1:……routine2:…………调试源程序基址变址寻址cmpal,0调试源程序34习题5.21 试写一程序,要求比较数组ARRAY中的三个16位补码数,并根据比较结果在终端上显示如下信息:(1)如果三个数都不相等,则显示0 (2)如果有两个相等则显示1(3)如果都相等,则显示2dsegsegment arraydw3dup(?)dsegendscsegsegment…… movcx,3 leasi,arraybegin: pushcx movcl,4 movdi,4 movdl,’‘ movah,02 int21hinput: movah,01h int21h andal,0fh shldx,cl ordl,al decdi jneinput mov[si],dx addsi,2 popcx loopbegin习题5.21 试写一程序,要求比较数组ARRAY中的三个135compa:leasi,array movdx,0 movax,[si] movbx,[si+2] cmpax,bx jnenext1 incdxnext1: cmp[si+4],ax jnenext2 incdxnext2: cmp[si+4],bx jnenum incdxnum: cmpdx,3 jldisp decdxdisp: movah,2 adddl,30h int21hmainendpcsegends endstartcompa:leasi,arraynum: cmp36习题5.23 已定义整型变量A、B(1)若只有一个奇数,奇数存入A,偶数存入B(2)若两个奇数,A=A+1B=B+1(3)若两个偶数,A、B值不变begin: movax,a movbx,b xorax,bx testax,1h jzclass;同奇同偶,转移 textbx,1h jzexit xchgbx,a movb,bx jmpexitclass: testbx,1h jzexit;若同偶,退出 incb incaexit: ret习题5.23 已定义整型变量A、Bbegin: mova375.3如何在实模式下发挥80386及其后继机型的优势80386及其后继机型不但兼容8086的程序,运行速度更快;而且还有其它的一些优势:5.3.1充分利用高档机的32位字长特征5.3.2通用寄存器可作为指针寄存器5.3.3与比例因子有关的寻址方式调试源程序例5.115.3如何在实模式下发挥80386及其后继机型的优势5.38通用寄存器作指针寄存器8个32位通用寄存器都可以作为基址或变址寄存器使用,但注意它们的高16位应为0。32位字长特征计算机一次能够处理32位的数据,可以访问32位的8个通用寄存器,但EIP和EFLAGS在实模式下只有低16位可以使用。比例因子方便了表格处理和多位数组处理实模式段的大小限于64K通用寄存器作指针寄存器32位字长特征比例因子实模式段的大小限39实模式下的程序是一种混合的16位和32位代码纯16位模块(1)所有段长都小于64KB;(2)数据项主要是8位或16位的(3)指向代码或数据的指针只有16位偏移地址(4)只有16位段之间传送控制纯32模块(1)段长可大于64KB(0-4GB);(2)数据项主要是8位或32位的(3)指向代码或数据的指针有32位偏移地址(4)只有32位段之间传送控制8086/80286实模式80386+保护模式实模式下的程序是一种混合的16位和32位代码纯16位模块纯340386+实模式下的程序在同一模块中,允许同时使用16位和32位的操作数和寻址方式段必须实16位的,但段中的指令可以是混合的16位和32位代码奔腾4386+实模式下的程序奔腾441第五章作业 Page193~1955.105.21

第五章作业42第五章循环与分支程序设计5.1循环程序设计5.2分支程序设计5.3如何在实模式下发挥80386及其后继机型的优势第五章循环与分支程序设计5.1循环程序设计43

1.编写汇编语言程序步骤l

分析实际问题,确定解决问题的算法l

按算法画出程序流程图l

按流程图编写程序l上机调试,运行程序注:本教材所讨论的编程环境只限于在DOS操作系统下的实模式

1.编写汇编语言程序步骤注:本教材所讨论的编程环境只限于442.判断程序质量的标准程序的正确性程序的可读性程序的执行时间程序所占内存大小2.判断程序质量的标准453.几种程序结构顺序结构循环结构分支结构子程序结构3.几种程序结构46顺序结构形式顺序结构形式47循环结构形式当型循环(当条件成立进入循环)循环初始设置循环体循环条件判断?YN直到型循环(直到条件成立退出循环)YN循环初始设置循环体循环条件判断?循环结构形式当型循环循环初始设置循环体循环条件判断?YN直到48两个分支YN

、、、CMPAL,BLJGgreat

JMPexitgreat:

exit:、、、、、、

AL≤BL处理AL>BL处理分支结构形式两个分支YN、、、AL≤BL处理AL>BL处49三个分支

、、、CMPAL,0

JGgreat

JLless

JMPexitless:

JMPexitgreat:

exit:、、、AL=0处理AL>0处理AL<0处理YYNN分支结构形式……三个分支、、、AL=0处理AL>0处理AL501.多处调用完成同一功能的子程:codeSEGMENTstart:、、

CALLsubp、、

CALLsubp、、

CALLsubp、、MOVAH,4CHINT21HsubpPROC、、、、RETsubpENDPcodeENDSENDstart2.模块化程序设计:codeSEGMENTbegin:CALL

sub1

CALLsub2

CALLsub3MOVAH,4CHINT21Hsub1PROC、、RETsub1ENDPsub2PROC、、RETsub2ENDPsub3PROC、、RETsub3ENDPcodeENDSENDbegin

子程结构形式注意返回DOS语句位置1.多处调用完成同一功能的子程:2.模块化程序设计:子程结构51开

始结

化循环的初始状态

体循环的工作部分及修改部分

控制条件

计数控制特征值控制地址边界控制5.1.1循环程序的结构形式5.1循环程序设计(1)DO-WHILE结构(2)DO-UNTIL结构开始结束初始化52有关字符、数码转换的处理1.计算机处理字符时,常用的字符编码是ASCII码。2.数字和字母的ASCII码是一个有序序列数字0~9:30H~39H大写字母A~Z:41H~5AH小写字母a~z:61H~7AH5.1.2循环程序设计方法例5.1将寄存器BX中的内容以十六进制形式显示出来。 有关字符、数码转换的处理5.1.2循环程序设计方法例5.53BX是一个16位寄存器二进制1010100100111110

用十六进显示时,每4位用一个字符显示,共4个其中:0000→’0’30H,1010→’A’41H

0001→’1’31H,1011→’B’42H、、、、

1001→’9’39H,1111→’F’46H?十六进制A93E屏幕上的显示‘A’‘9’‘3’‘E’对应的ASCII41H39H33H45HBX是一个16位寄存器用十六进显示时,每4位用一个字符显54BX1234BX155算法:取出要显示的某4位,转换为对应的ASCII码,再调用DOS系统功能进行显示。(1)对于0000~1001(0~9),先扩展成一个字节,高4位清0,加上30H后,即可得字符’0’~’9’对应的ASCII码。00000001B+30H=31H00001001B+30H=39H

0001B‘1’1001B‘9’(2)对于1010~1111(A~F),先扩展成一个字节,高4位清0,

加上30H后,还要再加上07H,才能得到’A’~’F’对应的ASCII码00001010B+30H+07H=41H00001111B+30H+07H=46H

1010B‘A’1111B‘F’算法:(1)对于0000~1001(0~9),先扩展56codeSEGMENTASSUMECS:codestart:MOVCH,4;字符个数rotate:MOVCL,4;循环移位次数

ROLBX,CL

;取显示位的值

MOVAL,BL

;保存在AL中

ANDAL,0FH

;清除高4位

ADDAL,30H

;转变为数字的ASCII

CMPAL,3aH;大于3aH,则应转变

JLprint;为数字0~9的ASCII

ADDAL,07H;为字母A~F的ASCIIprint:MOVDL,AL;送

ASCII字符到DLMOVAH,2;显示DL中的字符INT21HDECCH;显示结束?

JNZnextMOVAH,4CH;返回DOSINT21HcodeENDS

ENDstart显示字符个数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转换结束?开始codeSEGMENT显示字符个数CH=4BX循环左57例5.2在ADDR单元中存放着数Y,度编制一程序把Y中1的个数存入COUNT单元中。datareasegment addredw1234h countdw?datareaends movcx,0 movbx,addre movax,bxagain: testax,0ffffh jzexit jnsshift inccxshift: shlax,1 jmpagainexit: movcount,cx ret 例5.2在ADDR单元中存放着数Y,度编制一程序把Y中158例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

-1

3

5

49

15

52

23

37

105

99

78

65

32xn例5.4将正数n插入一个已整序的字数组的正确位置。59例5.5Zi=Xi+Yi

LOGIC_RULE DW 00DCH …… MOV BX,0 MOV CX,10 MOV DX,LOGIC_RULENEXT: MOV AX,X[BX]

SHR DX,1

JC SUBTRACT ADD AX,Y[BX] JMP SHORTRESULTSUBTRACT: SUB AX,Y[BX]RESULT: MOV Z[BX],AX ADD BX,2 LOOP NEXT RET ……例5.5Zi=Xi+Yi LOGIC_RULE DW 60例5.6键入一行以空格开头以空格结束的字符串datareasegment buffer db80dup(?) flag db?datareaends leabx,buffer movflag,0next: movah,01;读键盘 int21h;所读内容放入al testflag,01h;flag=1? jnzfollow;flag=0,zf=1不转 cmpal,20h;al是空格? jnzexit;不是,zf=0退出 movflag,1;置标志flag=1 jmpnextfollow: cmpal,20h;al是空格? jzexit;是,zf=1,退出 mov[bx],al;不是,保存 incbx;数组索引加1 jmpnextexit:20abcdef20flag=01jzexit成立例5.6键入一行以空格开头以空格结束的字符串datare615.1.3多重循环程序设计基本方法与单重循环相同,但要注意:1、分别考虑各重循环的控制条件及其程序实现,相互之间不能混淆2、每次从外层循环再次进入内层循环时,初始条件要重新设置5.1.3多重循环程序设计基本方法与单重循环相同,但要注意62例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;指向下一个数looploop2

movcx,di;恢复外循环次数looploop1例5.7将首地址为a的字数组从大到小排序(气泡算法,多重循63例5.8附加段字数组首地址存于DI,第1字存放长度,从小到大排序

extrasegment

adw10,10h,12h,32h,21h,11h,56h,43h,33h,3h,67h

extraendsdatasegment start_addrdw? save_cntdw?dataends leadi,a;取有效地址 movstart_addr,di movcx,es:[di];取长度 movsave_cnt,cx;数组长度init: movbx,1;结束标志 decsave_cnt jzsorted;zf=1,转移 movcx,save_cnt movdi,start_addrnext: adddi,2 movax,es:[di];取数 cmpes:[di+2],ax;比较 jaecont;>=,转移,不换 xchges:[di+2],ax moves:[di],ax subbx,bx;排序标志cont: loopnext cmpbx,0;bx=1,已排好 jeinitsorted: movdi,start_addr例5.8附加段字数组首地址存于DI,第1字存放长度,从小到64练习5.11:从键盘输入一系列以$结束的字符串,统计数字字符的个数datasegment countdw0 buffdb50dup(?)dataendsprognamsegmentmainprocfar assumecs:prognamstart: pushds subax,ax pushax movax,data movds,ax leabx,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: ret mainendpprognamends endstart练习5.11:从键盘输入一系列以$结束的字符串,统计数字字符65练习5.11:测试一字符串是否存在数字,若存在,置CL第5位置1,否则置0datasegmentstringdb'abcqdefghijklmnopqrs'dataendsprognam segmentmainprocfarassumecs: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;数组下标加1 loopagain andcl,0dfh;无数字,清5位exit: ret mainendpprognamends endstart练习5.11:测试一字符串是否存在数字,若存在,置CL第5位66循环程序设计小结1、循环控制条件的选择: a.循环次数已知,采用LOOP b.循环次数已知,但有可能使用其他特征或条件结束循环, 可采用LOOPZ和LOOPNZ c.循环次数未知,具体问题具体分析2、设立条件标志位的方法循环程序设计小结675.2分支程序设计5.2.1分支程序的结构形式双分支与多分支的共同特点:运行方向是向前的在某一种特定条件下,只能执行其中的一个分支5.2.1分支程序设计方法1、使用CMP、TEST等运算型指令+条件转移指令2、使用逻辑尺的方法3、使用跳跃表法实现CASE结构5.2分支程序设计5.2.1分支程序的结构形式双分支与68例5.9

折半查找:附加段有一个有序字数组,首字表示数组长度,AX是待查字,若找到CF=0,否则CF=1dsegsegmentlow_idxdw ?high_idxdw ?listdw12,11,22,33,44,55,66,77,88,99,111,222,333targetdw 77dsegendscsegsegmentmainprocfar assumecs:cseg,ds:dseg,es:dsegstart: pushds subax,ax pushax movax,dseg movds,ax moves,ax例5.9折半查找:附加段有一个有序字数组,首字表示数组长69例5.9

折半查找:附加段有一个有序字数组,首字表示数组长度,AX是待查字,若找到CF=0,否则CF=1 movax,target ; leadi,list;取数组首地址 cmpax,es:[di+2];取第1个数 jachk_last ;>第1个,检查最后1个 leasi,es:[di+2];<=第1个 jeexit ;=,退出 stc ;CF=1,没找到 jmpexitchk_last:movsi,es:[di] ;下面三条使SI指向

shlsi,1 ;数组末元素

addsi,di cmpax,es:[si] ;与末元素比较 jbsearch ;<,搜索数组 jeexit ;=,退出 stc ;CF=1,没找到 jmpexit0400list100102104106108例5.9折半查找:附加段有一个有序字数组,首字表示数组长70例5.9

折半查找:附加段有一个有序字数组,首字表示数组长度,AX是待查字,若找到CF=0,否则CF=1search: movlow_idx,1 ;搜索开始的地方 movbx,es:[di] ;数组长度 movhigh_idx,bx ;搜索结束的地方 movbx,di ;list地址mid: movcx,low_idx ; movdx,high_idx ;

cmpcx,dx ;比较’头’与’末’指针 jano_match ;>,’头’到’末’之后 addcx,dx ;以下三条计算 shrcx,1 ;’头’与’末’的中点 movsi,cx

shlsi,1 ;对准中间’字’0500100102104106108list10A(1+5)/2=33*2=6DI偏移6,即106,即第3字例5.9折半查找:附加段有一个有序字数组,首字表示数组长71compare: cmpax,es:[bx+si] ;比较,bx指向数组首元素 jeexit ;=,找到,退出 jahighter ;>,调节搜索’头’ deccx ;<= movhigh_idx,cx ;调节搜索’末’ jmpmidhighter: inccx movlow_idx,cx ;调节搜索’头’ jmpmidno_match: stcexit: ret例5.9

折半查找:附加段有一个有序字数组,首字表示数组长度,AX是待查字,若找到CF=0,否则CF=1compare:例5.9折半查找:附加段有一个有序字数组72例5.10

根据AL寄存器中哪一位为1(从低位到高位)把程序转移到8个不同的程序分支去。branch_tabledwroutine1

dwroutine2

dwroutine3

dwroutine4

dwroutine5

dwroutine6

dwroutine7

dwroutine8注意:DW标号的使用例5.10根据AL寄存器中哪一位为1(从低位到高位)把程73寄存器间接寻址cmpal,0jecontinueleabx,branch_tableL

:shral,1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论