版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第七章 汇编语言程序设计17.1 汇编语言程序设计的一般步骤汇编语言程序设计一般有以下几个步骤:p1461分析问题,确定算法2绘制流程图3根据流程图编制程序4调试程序27.1.1 流程图1流程图的概念 流程图是由特定的几何图形、指向线、文字说明来表示数据处理的步骤,形象描述逻辑控制结构以及数据流程的示意图。流程图具有简洁、明了、直观的特点。3(2)判断框 (3)处理框 (4)调用框 4(5)指向线 (6)连接框 57.1.2 程序结构基本程序结构: 顺序结构 循环结构 分支结构 子程序结构 复合结构:多种程序结构的组合67.2 程序设计顺序程序设计。【例】试编写一程序计算以下表达式的值。=(v
2、-(*+-540)/x式中x、v均为有符号字数据。设、的值存放在字变量、V中,结果存放在双字变量之中,程序的流程图如图所示。78源程序如下:DATASEGMENTXDW200YDW100ZDW3000VDW10000WDW2 DUP(?)DATAENDSSTACKSEGMENT STACK DB 200 DUP(0)STACKENDSCODESEGMENTASSUME DS:DATA,CS:CODE,SS:STACK9START:MOVAX,DATAMOVDS,AX;DATAAXMOVAX,X IMULY;(X)*(Y)DX:AXMOVCX,AXMOVBX,DX;(DX:AX)(BX:CX)M
3、OVAX,ZCWD;(Z)符号扩展ADDCX,AXADCBX,DX;(BX:CX)+(DX:AX)(BX:CX)SUBCX,540SBBBX,0;(BX:CX)-540(BX:CX)MOVAX,V 10CWD;(V)符号扩展SUBAX,CXSBBDX,BX;(DX:AX)-(BX:CX)(DX:AX)IDIVX;(DX:AX)/XMOVW,AX;商WMOVW+2,DX;余数DXW+2MOVAH,4CHINT21HCODEENDS;退出DOS 状态ENDSTART11分支程序设计条件转移指令(JNZ,JC等)和无条件转移指令JMP用于实现程序的分支结构,JMP不测试条件,Jcc可根据条件是否成立
4、决定转移到指定位置或不转移而顺序执行后续指令。由于条件转移指令不支持条件表达式,而是以当前标志位的状态为条件,故条件转移指令之前一定要安排设置标志位的指令,如加减法、比较、测试等指令。基本分支类型分为单分支和双分支。121. 单分支类型对同一个问题,根据选择的条件不同,单分支结构的流程图有两种画法,对应的程序也有两种编法。如计算AX中的有符号数的绝对值。13AX0 ?求补指令YN保存结果 cmp ax,0 jge noneg neg axNoneg: mov result,axAX0?求补指令YN保存结果JMP cmp ax,0 jnge yesneg jmp done yesneg: neg
5、 axDone: mov result,ax142.双分支程序两个分支都有语句体,如何选择条件不重要。流程图中分支体的位置就是程序的实际顺序,故分支语句体最后一定要有一条指令,跳过语句体,转移到“后续操作”。条件成立?分支语句体2YN分支语句体1 后 续 操 作 15双分支举例:显示BX的最高位。shl bx,1jc one ;转分支体 mov dl,0 ;分支体1 jmp next;转后续操作One: mov dl,1 ;分支体2next: mov ah,2 ;后续操作 int 21h分支程序的其他问题有些双分支问题可以先假设一种情况,把双分支改成单分支问题。如上例,先假设BX最高位为0,在
6、分支外准备显示0;如最高位为0,即可直接跳到后续操作;如最高位为1才需要执行分支体。163.多分支程序分支的嵌套形成多分支,嵌套形式多种多样。 例1:求符号函数 1 当 X0 Y= 0 当 X=0 -1 当 XS2,转移mov ah,- ; 若S1S2,修改结果为xchg si,di ;指针交换jmp next2next1:inc bx ;指针指向下一位loop lop133next2:mov result,ah ;存结果符号lea bx,result+3 ;置结果存放指针mov cx,3 ;置循环次数clclop2:mov al,si ;由低位开始,依次相减sbb al,di ;同位相减aa
7、s ;十进制调整lahf ;保存标志位在AH中or al,30h ;同位相减的差转换为ASCII码mov bx,al ;存结果sahf ; 恢复标志位dec si ;修改被减数指针dec di ;修改减数指针dec bx ;修改结果指针loop lop2 ;循环控制34lea dx,result0 ;显示结果mov ah,09hint 21h mov ah,4ch int 21h main endpprogram endsend start35例7-9 试编制一个计算XY的程序。 Title mathematical power(ex6-2-1)data segmentvarxdw 5 ;变量
8、Xvarydw 6 ;变量Ypowerdw ? ,? ;存结果data endsprogram segmentmain proc far assume cs:program,ds:data,ss:stack1start: mov ax,data mov ds,ax36 mov ax,varx ;取自乘数 mov cx,vary ;取自乘次数 dec cx je exit ;自乘次数=1,转移 mov dx,0lop: mul varx ;自乘 loop lopexit: mov power,ax ;存结果 mov power+2,dx ;存结果高位 mov ah,4ch int 21h mai
9、n endpprogram endsend start37例7-10 试用乘法指令实现32位二进制数的乘法 Title mathematical power(ex6-2-2)stack1 segment para stack db 5 dup (stack)stack1 endsdata segmentnum1 dw 1220h,48a2h ;0h,1h a,bnum2 dw 2398h,0ae41h ;c,dprodu dw 4 dup(0) ;存放乘积 ;produhigh ,produ+6-low db enddata ends38program segmentmain proc far
10、 assume cs:program,ds:data,ss:stack1start:mov ax,data mov ds,axxor dx,dxmov ax,num2+2 ;取Dmul num1+2 ;完成B*Dmov produ+6,ax ;存最低位mov produ+4,dx ;存乘积高位mov ax,num2+2 ;取Dmul num1 ;完成A*Dadd produ+4,ax ;加乘积低位adc produ+2,dx ;加乘积高位39 adc produ,0 ;加进位mov ax,num2 ;取Cmul num1+2 ;完成B*Cadd produ+4,ax ;加乘积低位adc pro
11、du+2,dx ;加乘积高位adc produ,0 ;加进位mov ax,num2 ;取Cmul num1 ;完成A*Cadd produ+2,ax ;加乘积低位adc produ,dx ;加乘积高位 mov ah,4ch int 21h main endpprogram endsend start40例7-11 试编制一程序,找出从2开始的前N个质数,并依次存放在NUM开始的字单元中。 Title ex7-11(ex6-2-3)stack1 segment para stack db 5 dup (stack)stack1 endsdata segmentcountdb 20h ;指定质数个
12、数numdw 40h dup(0) ;存放质数data endsprogram segmentmain proc far assume cs:program,ds:data,ss:stack1start: mov ax,data mov ds,ax41 lea di,num ;存放质数指针初始值mov cl,count ;取质数个数xor dh,dh ;初始化xor ch,chmov word ptr di,2 ;存储第一个质数add di,2 ;修改地址指针mov word ptr di,3 ;存储第二个质数sub cx,2 ;从第三个开始查找新质数mov dl,5 ;待查找新质数起点mov
13、 bl,3 ;除数起点mov bh,3 ;置最大除数lop:xor ah,ah mov al,dl ;取一个试探新数在AX中div bl ;除一个奇数cmp ah,0 ;能整除吗?je next1 ;能整除,不是质数,转走42 add bl,2 ;不能整除,找新除数cmp bl,bh ;新除数大于等于最大除数?jae next2 ;是质数,转走jmp lop ;不是质数,继续查证next1:add dl,2 ;不是质数,确定下一个待查找数 mov bh,dl ;确定新的最大除数,存在BH中shr bh,1 ;取其一半做最大除数mov bl,3 ;重新置除数起点jmp lopnext2:add
14、di,2 ;修改地址指针mov di,dx ;存放新质数add dl,2 ;下一个待查找数mov bh,dl ;确定新的最大除数shr bh,1 ;取其一半做最大除数mov bl,3 ;重新置除数起点loop lop ;质数个数计数未满,继续43mov ah,4ch int 21h main endpprogram endsend start44代码转换程序设计45例7-12将ASCII码表示的两位十进制数转换成一字节二进制数。Data segmentAsdec db 37h,35hBin db ?Data ends code segment assume cs:code,ds:dataSta
15、rt: mov ax,data mov ds,ax mov si,offset asdec mov al,si sub al,30h46 sal al,1 ;采用移位指令乘10,优点? mov bl,al mov cl,2 sal al,cl add bl,al inc si mov al,si sub al,30h add al,bl mov bin,al mov ah,4ch int 21hCode ends end start47例7-13将ASCII码表示的两位十六进制数转换成一字节二进制数。Data segment ashex db 41h,36h bin db ?Data ends
16、Code segment assume cs:code,ds:data start: mov ax,data mov dx,ax mov si,offset ashex48 mov al,si sub al,30h cmp al,0ah Jb next1 Sub al,7Next1:mov cl,4sal al,cl mov bl,al inc si mov al,si sub al,30h cmp al,0ah49 jb next2 sub al,7Next2: or al,bl mov bin,al mov ah,4ch int 21hCode ends end start;将ASCII码
17、表示的数转换为十六进制数值时需考虑两种情况1.3039h 2.41H46h50例7-14将一字节二进制数转换成ASCII码表示的十进制数。DATA SEGMENTBIN DB 01001111BASDEC DB 2 DUP(?)DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX MOV DI,OFFSET ASDEC XOR AX,AX MOV AL,BINAGAIN: SUB AL,10 JB NEXT INC AH JMP AGAIN51NEXT: ADD AL,10 ADD AH,30H MOV
18、 DI,AH INC DI ADD AL,30H MOV DIAL MOV AH,4CH INT 21HCODE ENDS END START52例7-15将ASCII码表示的5位十进制数(小于65535)转换成两字节二进制数。Data segment asdec db 33h,39h,35h,33h,34h count equ $-asdec bin dw ? data endsCode segment assume cs:code,ds:dataStart: mov ax,data mov ds,ax53mov si,offset asdec mov cx,countxor ax,axAg
19、ain: add ax,axmov bx,axadd ax,axadd ax,axadd ax,bxmov bh,0mov bl,si54 Sub bl,30hadd ax,bxInc siLoop againMov bin,axMov ah,4chInt 21hCode ends end start557.2 串的处理串操作指令 :数据传送类指令每次只能传送一个数据,若要传送大批数据就需要重复编程,这样就浪费了大量的时间和空间。为此8086提供了一组处理主存中连续存放数据串的指令,下例就是有重复前缀repz串操作指令。 56串操作流程图57串操作指令举例 ;例7-16 在STRBUF字符串中
20、,寻找STRING中指定的字符串个数。stack1 segment para stack db 5 dup (stack)stack1 endsdata segmentstrbufdb asasaasassassaasasas ;被搜索字符串cunt equ $-strbuf ;被搜索字符串字符个数stringdb as ;要搜索字符串numdb ? ;搜索到的个数data endsprogram segmentmain proc far assume cs:program,ds:data,ss:stack1start:58 mov ax,data mov ds,ax ;设置数据段mov es
21、,ax ;设置扩展段与数据段在同一段lea si,strbuf ;取源串首址lea di,string ;取目的串首址mov cx,cunt-1 ;置源串字符个数mov bl,0 ;置计数器初值cld ;置方向为增量方式lop:cmpsw ;字串比较(比较后SI,DI自动加2)jne next ;不相等,查下一个inc bl ;相等,计数器加一next:dec si ;修改源串指针,后移一位 lea di,string ;目的串首址恢复dec cx ;待查字符个数减一jg lop ;未结束,查下一个59 mov num,bl ;存统计数mov ah,4ch int 21h main endpp
22、rogram endsend start60 ;例试编制一程序,比较BUF与STRING两个字符串,把完全相同的字符个数送RESU单元中。(ex7-2-2)stack1 segment para stack (自看) db 5 dup (stack)stack1 endsdata segmentbufdb abcdefghijklmnop ;被比较字符串cunt equ $-buf ;被比较字符串字符个数stringdb abcdefghijklmnop ;要比较的字符串resudb ? ;找到的相同字符个数data endsprogram segmentmain proc far assum
23、e cs:program,ds:data,ss:stack1start:61mov ax,data mov ds,ax ;设置数据段mov es,ax ;设置扩展段与数据段在同一段mov si,offset buf ;取源串首址mov di,offset string ;取目的串首址mov cx,cunt ;置源串字符个数mov bx,cx ;暂存源串字符个数cld ;置方向为增量方式repz cmpsb ;重复字节串比较,直到CX=0或者ZF不等于1jz end0 ;ZF=1,表示两字符串完全相同,转移sub si,offset buf ;ZF=0,表示中途跳出,计算相同字符个数mov bx
24、,si ;送BX,并修正dec bxend0:mov resu,bl ;存相同字符个数62 mov ah,4ch int 21h main endpprogram endsend start63 ;例7-17试编制一程序,在TXTBUF字符串中查找STRING指定的字符,若查到,则把该字符所在位置(1-N)送INDEX单元中;若未查到,便把0FFH送INDEX单元中。(ex7-2-3) stack1 segment para stack db 5 dup (stack)stack1 endsdata segmenttxtbufdb abcdefghijklmnop ;要查找的目的串cunt e
25、qu $-txtbuf ;目的串字符个数stringdb g ;要查找的字符indexdb ? ;所在位置data endsprogram segmentmain proc far assume cs:program,ds:data,ss:stack1start:64 mov ax,data mov ds,ax ;设置数据段mov es,ax ;设置扩展段与数据段在同一段mov di,offset txtbuf ;取目的串首址 mov cx,cunt ;置目的串字符个数mov bx,0ffh ;预置未查到标识mov al,string ;取要查找的字符cld ;置方向为增量方式repnz sc
26、asb ;重复字节串扫描,直到CX=0或者ZF=1(找到)jne end0 ;ZF=0,表示全部查完都没有找到,转移sub di,offset txtbuf ;ZF=1,表示中途跳出,已找到,所在位置 mov bx,di ;送BXend0:mov index,bl ;存标识 mov ah,4ch int 21h main endpprogram endsend start65 ;例 从键盘上输入两个长度不同的字符串,(设各自长度25个字符),要求在屏幕上以右边对齐的方式显示出来;。(ex7-2-4) (自看)stack1 segment para stack db 5 dup (stack)s
27、tack1 endsdata segmentnum equ 25prompt1db 0ah,0dh,string:,$ ;输入字符串的提示信息Prompt2 db 0ah,0dh,right-adjusting of string: ;右对齐字符串的提示信息 db 0ah,0dh,$String1 db num,0,num dup ( ),0ah,0dh,$ ;输入的第一个字符串String2 db num,0,num dup ( ),0ah,0dh,$ ;输入的第二个字符串data endsprogram segmentmain proc far assume cs:program,ds:d
28、ata,ss:stack166start:mov ax,data mov ds,ax ;设置数据段mov es,ax ;设置扩展段与数据段在同一段mov cx,2 ;设循环2次lea bx,string1 ;置第一个字符串存放位置lop:lea dx,prompt1 ;显示输入字符串的提示mov ah,09hint 21hmov dx,bx ;输入一个字符串mov ah,0ahint 21hlea bx,string2 ;置第二个字符串存放位置loop lop ;未完,继续输入下一个字符串右对齐处理lea bx,string1+2 ;置第一个字符串存放首址call move ;右对齐处理lea
29、 bx,string2+2 ;置第二个字符串存放首址call move ;右对齐处理67;输出右对齐字符串lea dx,prompt2 ;显示右对齐字符串的提示信息mov ah,09hint 21hlea dx,string1+2 ;置第一个字符串存放首址mov ah,09h ;显示第一个字符串int 21hlea dx,string2+2 ;置第二个字符串存放首址mov ah,09h ;显示第二个字符串int 21h mov ah,4ch int 21h main endp68 moveproc ;字符串右对齐处理子程序 xor ch,ch ;清零mov cl,-1bx ;取字符串字节数mo
30、v si,cx ;计算传送源串末地址add si,bx ;dec si ;修正,SI指向源串末地址mov di,bx ;计算传送目的串末地址add di,num-1 ;std ;设置DF为减量方式rep movsb ;字符串传送,使其右对齐mov cx,num;计算剩余字节数sub cl,-1bx ;mov al, ;AL预置空格rep stosb;存串,剩余字节填空格retmove endp program endsend start69表的处理 在计算机处理的数据中,有许多数据具有相同的属性,例如:一个班学生的学号、姓名、性别、某门课成绩等。将这些数据按照一定的格式或规律组织起来,形成一张
31、表格,我们就可以根据其格式寻找到其中任何一个数据,进行处理。例如:将12个月份的英文单词各取三个字符作为缩写表示,并依次排列成为一个月份缩写表,我们就可以根据月份来查出其缩写:一、表的构造70 ;例7-18 用查表法显示英文月份缩写。(ex7-3a) stack1 segment para stack db 5 dup (stack)stack1 endsdata segmentmontabdb jan,feb,mar,apr,may,jun ;英文月份缩写表 db jul,aug,sep,oct,nov,decmonth db 9 ;月份data endsprogram segmentmai
32、n proc far assume cs:program,ds:data,ss:stack171start: mov ax,data mov ds,ax ;设置数据段mov al,month ;取出月份的数字dec al;月份减1mov bl,al;乘3,得表内偏移量sal al,1add al,bllea bx,montab;取月份表首址add bl,al;形成该月英文缩写首址adc bh,072 mov cx,3 ;置显示字符个数lop:mov dl,bx ;取显示字符mov ah,2 ;显示int 21hinc bx ;修改地址指针loop lop ;未结束,显示下一个 mov ah,4
33、ch int 21h main endpprogram endsend start如果需要显示英文月份的全名,月份表中月份字符个数就要设为最大的一个(september 9个),其余不足9个字符的月份,后面填空格。73 ;例7-3b 假设一个班学生人数不超过9人,学生成绩表包含姓名和英语,数据结构,程序设计三门课成绩。为简化起见,这个表可以规定,9个学生姓名用A00-A09表示,姓名后依次存放字符型的三门课成绩,而且表是按学号为序排列好的。要求从键盘输入一个学号,然后从表中查找该学生的成绩并显示出来。 (自看)stack1 segment para stack db 5 dup (stack)
34、stack1 endsdata segmenttabldb a01,88,79,91,a02,78,83,77 ;学生成绩表 db a03,77,81,80,a04,91,92,93 db a05,69,82,90,a06,76,75,79 db a07,90,90,91,a08,66,69,82 db a09,88,79,91 List db name english data-stru programming,$ ;表头信息input db input number(0-exit):$ ;输入学号提示信息data ends74program segmentmain proc far ass
35、ume cs:program,ds:data,ss:stack1start: mov ax,data mov ds,ax ;设置数据段lop:call crlf ;显示回车换行lea dx,input ;显示提示信息mov ah,09int 21hmov ah,1 ;从键盘输入要查询的学号int 21hand al,0fh ;屏蔽学号高四位cmp al,0 ;学号是否为0je end0 ;学号为0退出dec al ;学号修正为序号75 call mult9 ;学号乘9,得表内偏移量(一个学生的信息9字节)lea bx,tabl ;取成绩表首地址add bl,al ;加上表内偏移量adc bh,
36、0 ;call crlf ;显示回车换行lea dx,list ;显示表头信息mov ah,09hint 21hcall disp ;显示该生成绩jmp lop ;循环查找end0: mov ah,4ch int 21h main endp76crlf proc ;回车换行子程序mov dl,0ah ;显示换行mov ah,6int 21hmov dl,0dh ;显示回车mov ah,6int 21hret crlf endpmult9 proc ;乘9子程序mov bl,al ;暂存ALsal al,1 ;AL*2sal al,1 ;AL*4sal al,1 ;AL*8add al,bl ;
37、加暂存值,得9倍值ret mult9 endp77;显示查找结果子程序disp proc call crlf ;显示回车换行mov cx,3 ;取显示字符个数3call disdl ;显示学生姓名mov dh,3 ;要显示三门成绩,DH做循环控制变量lop0:mov cx,8 ;取显示空格个数8call dispac ;显示空格mov cx,2 ;取显示字符个数2call disdl ;显示一门成绩dec dh ;循环控制变量减1jnz lop0 ;未结束,转去显示下一门成绩retdisp endp78dispac proc ;显示空格子程序,空格个数在CXlop1:mov dl, ;取一个空
38、格mov ah,6;单字符显示int 21hloop lop1;未结束,转去显示下一空格retdispac endpdisdl proc ;显示字符子程序,字符个数在CX中lop2:mov dl,bx;取一个字符mov ah,6 ;单字符显示int 21hinc bx;修改地址指针loop lop2 ;未结束,转去显示下一字符retdisdl endpprogram endsend start79二、表的插入 在一个数据表中,要插入一个数据,一般是将插入位置以后的数据依次往后移动,腾出所需的位置,再插入数据。MABCDEFGHIJ80例 已有一字符串STRING,按指定位置插入一个字符。 (自
39、看)stack1 segment para stack db 5 dup (stack)stack1 endsdata segmentstringdb 0dh,0ah,abcdefghij,5 dup (0),$ ;已有字符串stringcountequ $-string ;字符串长度prompt1db 0dh,0ah,location:$ ;输入位置提示信息prompt2 db 0dh,0ah,insert chara:$ ;输入字符提示信息data ends81program segmentmain proc far assume cs:program,ds:data,ss:stack1s
40、tart: mov ax,data mov ds,ax ;设置数据段lea dx,string ;显示原串string mov ah,09int 21hlea dx,prompt1;显示输入位置提示信息mov ah,09int 21hmov ah,1;输入插入位置int 21h ;AL中为位置数的ASCII码82and al,0fh ;屏蔽位置高四位inc al ;加1得后移要停止的位置mov bx,count-5 ; 取串长move:mov ah,stringbx ;后移字符mov stringbx+1,ah cmp al,bl ;是否插入位置je insert ;是,转插入dec bx ;
41、不是,指针前移一位jmp move ;继续后移insert: lea dx,prompt2 ;显示输入字符提示信息mov ah,09int 21hmov ah,1 ;从键盘输入字符int 21h83mov stringbx,al ;插入lea dx,string ;显示插入后的串 mov ah,09int 21h mov ah,4ch int 21h main endpprogram endsend start84例7-19 对已有一字符串STRING,按指定位置删除一个字符。删除操作,只需要找到要删除的位置,将后续的数据依次往前搬动,覆盖掉要删除的数据。 stack1 segment par
42、a stack db 5 dup (stack)stack1 endsdata segmentstringdb 0dh,0ah,abcdefghij,5 dup (0),$ ;已有字符串stringcountequ $-string ;字符串长度prompt1db 0dh,0ah,location:$ ;删除位置提示信息data ends85program segmentmain proc far assume cs:program,ds:data,ss:stack1start: mov ax,data mov ds,ax ;设置数据段 lea dx,string ;显示原串string mo
43、v ah,09 int 21h lea dx,prompt1 ;显示删除位置提示信息 mov ah,09 int 21h mov ah,1 ;输入删除位置 int 21h ;AL中为位置数的ASCII码86and al,0fh ;屏蔽位置高四位xor ah,ah ;AH清0,与AL组合lea bx,string ;取原串首址mov di,bx ;转存在DIadd bx,ax ;计算删除数据的地址add di,count-1 ;计算串尾地址 move:mov ah,bx+1 ;前移字符mov bx,ah inc bx ;修改地址指针cmp bx,di ;是否到字符串末尾jne move ;不是,
44、转继续前移mov byte ptr bx,00h ;最后字符填087lea dx,string ;显示删除后的串 mov ah,09int 21h mov ah,4ch int 21h main endpprogram endsend start88 排序 一个数据表,其中的数据如果按照某种顺序(递增或递减)排列,我们称其为有序表,否则是无序表。对无序表的处理和操作费时又复杂,效率很低。而有序表则效率高得多。所以,一般数据表都需要按照一定的顺序重新排列。这种处理叫做分类或排序。 排序方法有多种,其中冒泡排序是最基本,也最常见的一种。89 “冒泡法排序” 不是最优的算法,但它易于理解和实现。 冒
45、泡法从第一个元素开始,依次对相邻的两个元素进行比较,如次序对,则不交换两数位置;如次序不对则将这两个数位置交换,这样使前一个元素不大于后一个元素;将所有元素比较完之后,最大的元素排到了最后;然后,除掉最后一个元素之外的元素依上述方法再进行比较,得到次大的元素排在后面;如此重复,直至完成就实现元素从小到大的排序。 这是一个双重循环程序结构。可以看出,第一遍需比较(N-1)次,此时,最大的数已经放到了最后;第二遍比较只需考虑剩下的(N-1)个数,即只需比较(N-2)次;第三遍只需比较(N-3)次,整个排序过程最多需(N-1)遍。90 内循环次数是按每循环一次减1的规律变化的,是确定值,可用loop
46、指令实现;而外循环次数则不一定要进行N-1次,因为每进行一次内循环,凡是不符合顺序的数据都交换位置,有可能在外循环尚未全部完成前就排好了顺序,这样外循环就可以提前结束。所以,我们可以在每次内循环之前设置一个交换标志位为0,在内循环中,有交换就将标志位置位0FFH,每次内循环结束后,检查交换标志,一旦交换标志为0,则表示已经排好序,可以提前退出外循环,这种办法可以使排序效率提高很多,特别是数据表很大的情况。91例:数据表108169032第一遍101690328第二遍169032108第三遍90321610892 ;例 冒泡排序 。stack1 segment para stack db 5 d
47、up (stack)stack1 endsdata segmentdadb 80,3,-20,116,9,120,-6,62,-32,42 ;数据表countequ $-da ;数据表长度data endsprogram segmentmain proc far assume cs:program,ds:data,ss:stack1start: mov ax,data mov ds,ax ;设置数据段93mov dx,count-1 ;大循环次数初值sort1:mov bl,0 ;设交换标志初值mov cx,dx ;内循环比较次数初值mov si,0 ;数据首址sort2:mov al,das
48、i ;取一相邻数据项cmp al,dasi+1 ;比较,是否要交换数据项?jge noxchg ;大于等于,不交换 ;可改试jge,jl,有符号 jae,jb无符号xchg al,dasi+1 ;小于,交换mov dasi,al ;mov bl,0ffh ;置已交换标志noxchg:inc si ;修改地址指针loop sort2 ;内循环控制94dec dx ;大循环次数减1cmp bl,0 ;本次循环是否有交换?jne sort1 ;有交换,继续排序 mov ah,4ch ;无交换,排序结束 int 21h main endpprogram endsend start95查找 要在一个数据
49、表中查找某一个数据项,最简单的方法是顺序查找,如果数据项不在表中,或者是最后一个,查找就必须从头查到尾,这种查找的平均次数是N/2,效率很低。 二分查找是在有序表的基础上,将表划分成一系列依次对半减少的空间,逐步缩小范围。首先查找表的中间数据项,如果是要找的数据项,则查找成功,如果不是,则根据中间数据项比要查找的数据项大还是小,确定下一步是在上半部份还是下半部分查找;然后又取这一半的中间数据项比较,若相同,则查找成功,若不相同,则根据它们比较的大小,再次判断要查找的数据项在哪一小半.,如此反复,直到查找成功或者剩下的一小半不复存在为止。 这种算法称对分查找法,对于有N个数据项的有序表,它的最多
50、查找次数是log2N次,是用得最多,效率很高的一种算法。96例 在一个由大到小排好序的数据表中,采用对分查找法查找数据,若查找成功,将其在表中的位置送LOCA单元,若查找失败,把全1送LOCA单元。stack1 segment para stack db 5 dup (stack)stack1 endsdata segmenttabledb cunt-1,7fh,7ah,79h,73h,70h,6eh,6bh,6ah db 5dh,5ch,5ah,59h,55h,54h,50h,4dh,4ch,4ahdb 49h,48h,44h,41h,40h,3eh,3dh,3ah,39h,36hdb 35
51、h,32h,30h,2ch,25h,23h,1fh,19h,15h,00h;有序表cuntequ $-table ;有序表长度da0db 32h ;要查找的数据locadw ? ;存查找结果data ends97program segmentmain proc far assume cs:program,ds:data,ss:stack1start: mov ax,data mov ds,ax ;设置数据段mov bx,1 ;计算查找表的长度使其等于2nmov ax,cunt-1 ;取查找表长度leng:cmp bx,ax ;比较jae search ;大于等于则开始搜索sal bx,1 ;不
52、大于,乘2jmp leng ;重新比较;BX存对分点位置,DX存剩余表长,AL存待查找的数search:mov cx,cunt-1 ;最后一个数据项位置shr bx,1 ;除2,得第一个对分点mov dx,bx ;剩余表长mov al,da0 ;取待查找的数在AL中98;BX存对分点位置,DX存剩余表长,AL存待查找的数comp:cmp al,tablebx ;比较je end0 ;已查到,转移到结束pushf ;未查到,保护标志位cmp dx,0 ;表已查完?je nofund ;是,转移到结束popf ;恢复标志位,继续查找jg up ;大于,往数据表高端查找shr dx,1 ;小于,向下
53、查,剩余表长除2对分add bx,dx ;对分位置加剩余表长jmp next ;up:shr dx,1 ;向上查,剩余表长除2对分sub bx,dx ;对分位置减剩余表长next:cmp bx,cx ;对分点落在表外?jb comp ;不是,转移到继续查找jmp up ;是,向上找对分点nofund:mov bx,0ffffh ;未查到,BX置常数popf ;end0:mov loca,bx ;存结果99 mov ah,4ch int 21h main endpprogram endsend start100补充例题: 把BX中的二进制数以十六进制的形式显示在屏幕上。(自看) BX123410
54、1 mov ch, 4rotate: mov cl, 4 rol bx, cl mov al, bl and al, 0fh add al, 30h ;0-9 ASCII 30H-39H cmp al, 3ah jl printit add al, 7h ;A-F ASCII 41H-46Hprintit: mov dl, al mov ah, 2 int 21h dec ch jnz rotate 102例2. 将正数n插入一个已整序的字数组的正确位置。算法: 将数组中数逐个与N比较,Si为指针若NKi,则Ki下移一个单元若NKi,则插在Ki的下一个单元,并结束临界条件:若NKn,则插入Kn
55、的下一个单元若NK1,则K1Kn后移一个单元, N插在第一个单元循环控制:计数控制元素个数=(字末地址字首地址) / 2) +1 字数 = (字节末地址字节首地址) +1 字节数地址边界控制结束地址为ARRAY_HEAD特征值控制: 表示结束条件的值103例2. 将正数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, 0compare: cmp array_endsi, ax
56、 jle insert mov bx, array_endsi mov array_endsi+2, bx sub si, 2 jmp short compareinsert: mov array_endsi+2, ax -1 3 5 49 15 52 23 37 105 99 78 65 32xn104例3 (自看) 将首地址为A的字数组从小到大排序(气泡算法,多重循环) A dw 32,85,16,15, 8 序号 地址 数比 较 遍 数12341 A 322 A+2 853 A+4 164 A+6 155 A+8 8321615885161583285158163285815163285
57、105 mov cx, 10 dec cxloop1: mov di, cx mov bx, 0loop2: mov ax, Abx cmp ax, Abx+2 jle continue xchg ax, Abx+2 mov Abx, axcontinue: add bx, 2 loop loop2 mov cx, di loop loop1106 过程(子程序)定义伪操作procedure_name PROC NEAR ( FAR ) procedure_name ENDP(1)NEAR属性:调用程序和子程序在同一代码段中 (段内调用)(2)FAR属性:调用程序和子程序不在同一代码段中 (段
58、间调用)7.7 子程序的设计方法107保存与恢复寄存器subt proc far push ax ;保存 push bx push cx push dx .;子程序体 . . pop dx ;恢复 pop cx pop bx pop ax retsubt endp108 子程序调用(中断调用):隐含使用堆栈保存返回地址call near ptr subp (1) 保存返回地址 (2) 转子程序 (IP) subp的偏移地址call far ptr subp (1) 保存返回地址 (2) 转子程序 (CS) subp的段地址 (IP) subp的偏移地址 (IP)(SP) (IP)(SP) (C
59、S)子程序的调用和返回109INT n (n : 中断类型号) (1) 保存现场和返回地址(FLAGS,CS,IP入栈) (2) 转中断处理程序 (IP) (n*4) (CS) (n*4+2)子程序返回: (1)ret (返回地址出栈) (2)iret (IP,CS,FLAGS出栈)(IP)(SP) (CS)(FLAGS)int 21H110子程序的参数传送 (1)通过寄存器传送参数 (2)通过存储区传送参数 *子程序和调用程序在同一程序模块中,则子程序可 直接访问模块中的变量。 *子程序和调用程序不在同一程序模块中,则有两种 传送方式:建立公共数据区和使用外部符号。 (3)通过地址表传送参数
60、地址 (4)通过堆栈传送参数或参数地址111例3. 十进制到十六进制的转换程序(通过寄存器传送变量)Decihexsegment ; 1016 assume cs: decihexmain proc far push ds sub ax, ax push axrepeat: call decibin ; 102 call crlf call binihex ; 216 call crlf jmp repeat retmain endp112Decibinproc near ; 102 mov bx, 0 ;bx存十进制数newchar: mov ah, 1 int 21h sub al, 30
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- Unit 3 Where did you go(说课稿)-2023-2024学年人教PEP版英语六年级下册
- Unit 6 Review Period 4 (说课稿)-2024-2025学年北师大版(三起)英语三年级上册
- 《1、了解学习好习惯》(说课稿)-2024-2025学年二年级上册综合实践活动鲁科版
- 《10 交通安全小常识》(说课稿)-2023-2024学年四年级上册综合实践活动长春版
- 23《梅兰芳蓄须》说课稿2024-2025学年统编版语文四年级上册
- 14《我要的是葫芦》第一课时 说课稿-2024-2025学年语文二年级上册统编版
- Unit5 The colourful world第三课时(说课稿)-2024-2025学年人教PEP版(2024)英语三年级上册
- 2024-2025学年高中历史 第四单元 工业文明冲击下的改革 第12课 俄国农奴制改革(2)教学说课稿 岳麓版选修1
- 2025合同约定的“滞纳金”是否可以视为违约金
- 2025建安施工合同文本
- 2024-2025学年人教新版九年级(上)化学寒假作业(九)
- 2024年计算机二级WPS考试题库(共380题含答案)
- 2022年全国医学博士英语统一考试试题
- 2024年江苏农牧科技职业学院单招职业适应性测试题库参考答案
- 知识图谱与大模型融合实践研究报告
- 卫生专业技术资格考试卫生检验技术(初级(师)211)专业知识试题及答案指导
- 0-9任意四位数手机密码排列组合全部数据列表
- 小数加减乘除计算题大全(300题大全)
- 钢筋工考试卷(满分100分)
- 心内科康复护理个案
- 招聘会会展服务投标方案(技术方案)
评论
0/150
提交评论