1、1,新 编 汇编语言程序设计,2,第四章 选择和循环,4.1 测试和控制指令 4.2 选择结构程序4.3 循环结构程序4.4 程序的调试习题四,3,按照指令执行的顺序,程序的结构可以划分成以下三种。顺序结构:程序按照它编写的顺序执行,每条指令只执行一 次,这样的程序称为“顺序结构”的程序。循环结构:一组指令被反复地执行,这样的程序称为“循环结 构”或者“重复结构”的程序。选择结构:根据某个条件,一部分指令被执行,另一部分指 令没有被执行,这样的程序称为“选择结构”或者 “分支结构”的程序。一个实际运行的程序,常常是由以上三种结构的程序组合而成的,上面的三种结构称为程序的“基本结构”。使用这三种
2、基本结构,可以编写出任何所需要的程序。,4,4.1 测试和转移控制指令,4.1.1 无条件转移指令 4.1.2 比较和测试指令 4.1.3 条件转移指令,5,执行JMP指令后,程序转移到新的“目的位置”执行。,4.1.1 无条件转移指令,无条件转移指令的一般格式:,JMP 目的位置,6,CODE SEGMENTASSUME CS: CODE START: MOV DL, 20H ONE: MOV AH, 2INT 21H ;输出DL中的字符INC DL ;修改DL中的字符代码JMP ONE ;转移到“ONE”处继续执行MOV AX, 4C00HINT 21H CODE ENDSEND STAR
3、T,例4-1 用JMP指令实现转移,7,1.近程无条件转移指令如果转移的目的位置与出发点在同一个段里,这样的转移称为“近程”转移或者“段内”转移。实现“近程”转移,实质上是把目标位置的“偏移地址”置入IP寄存器。按照寻址方式的不同,近程无条件转移指令有三种格式。,8,(1)短转移 如果目的位置离开出发点很近,可以使用以下格式: JMP SHORT LABEL 其中“LABEL”是目的位置的标号。这种格式产生的机器指令代码最短,为2字节。,100H: JMP SHORT TWO 102H: 10CH: TWO: ,指令“JMP SHORT TWO”汇编后产生的机器指令为“EB0A”。 “EB”是
4、这种类型转移指令的“操作码”,“0A”是目的位置离开出发点的距离,10CH102H=0AH。由于用一个字节补码表示目的地址与当前地址的距离,所以转移范围为下一条指令地址-128 +127字节以内。,9,(2)近程直接转移JMP 目的位置标号,指令“JMP TWO”汇编后得到的机器指令代码为“E9FDEE”。 “E9”为操作码 “0EEFDH”为位移量,0EEFDH=0F000H103H。 指令“JMP ONE”对应的机器指令代码为“E90011” “E9”为操作码 位移量“1100H”,0F003H+1100H=0103H(舍去进位) 使用近程直接转移指令可以实现同一个段内64KB范围的转移。
5、,100H: JMP TWO 103H: ONE: 0F000H: TWO:JMP ONE 0F003H: ,10,(3)近程间接转移把转移的目的地址事先存放在某个寄存器或存储器单元中,通过这个寄存器或存储单元实现转移。,JMP CX ;寄存器间接转移,可使用任何一个通用寄存器 JMP WORD PTRBX;存储器间接转移,目的地址在存储单元中,11,1)JMP ONE ;近程直接转移 2)LEA DX, ONEJMP DX ;寄存器间接段内转移 3)LEA BX, TARGETJMP WORD PTRBX ;存储器间接段内转移 4)JMP TARGET ;存储器间接段内转移,已在数据段定义存
6、储器单元“TARGET” :TAEGET DW ONE 下面四组指令都可以实现向标号“ONE”的转移:,12,远程无条件转移指令可以实现不同的段之间的转移,执行该指令时,CPU把目的段的段基址装入CS,目的位置的段内偏移地址装入IP。有直接寻址和间接寻址两种格式。 (1)远程直接转移 JMP FAR PTR 远程标号 指令汇编后,对应的机器指令为5个字节:1个字节操作码“0EAH”2个字节目的地址的段内偏移地址2个字节目的标号所在段的段基址,2远程无条件转移指令,13,(2)远程间接转移远程转移需要32位的目的地址,使用间接转移时,需要把32位目的地址事先装入用“DD”定义的存储单元。,1)J
7、MP FAR PTR TWO ;远程直接转移 2)LEA BX, FAR_TGTJMP DWORD PTRBX ;远程间接转移 3)JMP FAR_TGT ;远程间接转移,假设已在数据段定义存储器单元“FAR_TGT”如下:FAR_TGT DD TWO 下面三组指令都可以实现向远程标号“TWO”的转移:,14,4.1.2 比较和测试指令,(1)CMP(Compare, 比较)指令 指令格式:CMP 目的操作数,源操作数 目的操作数:8位/16位/32位的寄存器/存储器操作数。 源操作数:与目的操作数同类型的寄存器/存储器/立即数。 功能:目的操作数-源操作数,保留运算产生的标志位,不保留 运算
8、的差。用来比较两个有符号数或无符号数的大小。,15,假设(ECX)= 8090A0B0H,指令“CMP ECX, 0”执行后:ZF=0 (ECX) 0OF=0 减法操作没有产生溢出(SF是正确的结果符号位)SF=1 如果ECX中存放的是有符号数,这个数是负数CF=0 如果ECX中存放的是无符号数,这个数大于0 这条指令与下面的指令等效:OR ECX, 0 ;根据ECX的值确定SF,ZFAND ECX, 0FFFFFFFFH ;根据ECX的值确定SF,ZFXOR ECX, 0 ;根据ECX的值确定SF,ZF,16,CF=0,目的操作数源操作数 CF= 1, 目的操作数源操作数,对于有符号数:OF
9、=0时,SF为正确的结果符号 OF=1时,SF与正确的符号位相反 OFSF的运算结果反映了正确的结果符号,OFSF= 0, 目的操作数源操作数 OFSF= 1, 目的操作数源操作数,对于无符号数:,17,ZF=0 (X) 5 OF=0 减法操作没有产生溢出,SF是正确的结果符号位 SF=1 如果X中存放的是有符号数,X5,假设存储器变量(X)= 80H,指令“CMP X, 5”执行后:,18,(2)TEST(Test,测试)指令 指令格式:TEST 目的操作数,源操作数 目的操作数:8位/16位/32位的寄存器/存储器操作数。 源操作数:与目的操作数同类型的寄存器/存储器/立即数。 功能:TE
10、ST指令将目的操作数与源操作数进行逻辑乘运算,保 留运算产生的各标志位,但是不保留逻辑乘的结果。该 指令用来测试目的操作数中某几位二进制的特征。,19,如果ZF = 0, 说明BL寄存器的D2D100,这两位为01,10或11。 如果ZF = 1,说明BL寄存器的D2D100,这两位为00。,指令 TEST VAR, 1 执行后:,如果ZF = 0,说明变量VAR的D0位为1,该数为奇数 如果ZF = 1,说明变量VAR的D0位为0,该数为偶数,指令 TEST BL, 6 执行后:,20,(3)BT(Bit Test,位测试)指令 指令格式:BT 目的操作数,源操作数 目的操作数: 16位/3
11、2位的寄存器/存储器操作数。 源操作数:与目的操作数同类型的寄存器操作数或0255以内 的立即数。 功能:BT指令将目的操作数内部由源操作数指定的那一位二进 制的值送入CF,两个操作数的值均不改变。该指令用来 测试目的操作数中某一位二进制的值。,21,BTS 目的操作数,源操作数 ;测试目的操作数的指定位,并把该位置为1 BTR 目的操作数,源操作数 ;测试目的操作数的指定位,并把该位置为0 BTC 目的操作数,源操作数 ;测试目的操作数的指定位,并把该位取反,设(EDX)= 12345678H, (ECX)= 5,BT EDX, ECX ; 由于EDX寄存器D5=1,执行后CF= 1,EDX
12、值不变 BT EDX, 2 ; 由于EDX寄存器D2=0,执行后CF= 0,EDX值不变,与BT指令类似的还有以下三条指令:,22,4.1.3 条件转移指令,“J”是条件转移指令操作码的第一个字母“cc”是代表转移条件的13个字母“label”是转移目的地的标号。,条件转移指令格式:,Jcc label,23,(1)根据两个有符号数比较结果的条件转移指令 两个有符号数的比较结果通过OF,SF,ZF反映出来,G (Greater,大于)L (Less,小于)E (Equal,等于)N (Not,否),例:JG 大于(不小于等于)则转移JNL 不小于(大于或等于)则转移JE 等于(为零)则转移,2
13、4,根据有符号数大小的条件转移指令,25,MOV AX, X ;取出X的值送AX CMP AX, Y ;比较两个操作数,建立需要的标志位 JG GREATER ;如果XY,转移到 “GREATER”处执行 JE EQUAL ;如果X=Y,转移到 “EQUAL”处执行 LESS: ;否则,执行标号“LESS”处的指令 GREATER: EQUAL:,下面程序根据有符号字变量X和Y的大小决定程序的走向。,26,SUB AX, BX ;AX(AX)(BX), 建立标志位JGE SKIP ;如果(AX)0,转标号“SKIP”NEG AX ;如果(AX)0,把AX的值取反 SKIP:,JG GREATE
14、R ;如果XY,转移到 “GREATER”处JE EQUAL ;如果X=Y,转移到 “EQUAL”处JL LESS ;如果XY,转移到 “LESS”处 LESS: ,这个程序能够正确运行,最后一条指令有“画蛇添足”之嫌。,下面的程序计算 AX = |AXBX|,27,(2)根据两个无符号数比较结果的条件转移指令两个有符号数的比较结果通过CF,ZF反映出来,代表转移条件的字母:,A(Above,高于)B(Below,低于)E(Equal,等于),28,根据无符号数大小的条件转移指令,29,(3)根据单个标志位的条件转移指令,30,JNG SkipJMP Label Skip: ,对于16位80X
15、86CPU,条件转移指令的转移范围在下一条指令地址128127字节之间。如果转移目的位置超出了上述范围,汇编时将报告错误。,对于32位80X86CPU,条件转移指令汇编后产生4字节机器代码,前2字节是它的操作码,后面2字节是表示转移距离的位移量,可以实现64KB范围内的转移。,JG Label ;如果标号“Label”超出范围,汇编时将出错,可以把上面指令修改为:,31,(4)根据CX/ECX寄存器值的条件转移指令 指令格式:JCXZ Label ;若CX=0,转移到LabelJECXZ Label ;若ECX=0,转移到Label 它们的转移范围固定为下一条指令地址128127字节以内。,3
16、2,4.2 选择结构程序,4.2.1 基本选择结构 4.2.2 单分支选择结构 4.2.3 复合选择结构 4.2.4 多分支选择结构,33,为“|X|3”和“|X|3”分别编制了进行不同处理的指令序列。 如果条件“|X|3”成立(为“真”),执行 “Y=3X5” 如果条件“|X|3”不成立(为“假”),执行Y=6通过在不同的程序之间进行选择,实现程序的不同功能,“选择结构”因此得名。,计算分段函数的值,34,4.2.1 基本选择结构,35,CODE SEGMENT ASSUME CS: CODE START: JMP BEGIN X DB ? ; 被测试的数,汇编之前置入 YES DB 0AH
17、, 0DH, “Its a even number.”, 0AH, 0DH, $ NO DB 0AH, 0DH, “Its a odd number.”, 0AH, 0DH, $ BEGIN:PUSH CSPOP DS,例4-2 判断变量X的值是否为“偶数”,36,TEST X, 1 ;测试X的最低位,确定是否为偶数JZ EVN ;ZF=1,该数是偶数,转向“EVN” ODD: LEA DX, NO ;否则,该数是奇数MOV AH, 9INT 21H ;输出奇数的相关信息JMP DONE ;跳过程序“EVN” EVN: LEA DX, YESMOV AH, 9INT 21H ;输出偶数的相关信
18、息 DONE:MOV AX, 4C00HINT 21H CODE ENDSEND START,37,TEST X, 1 ;测试X的最低位,确定是否为偶数JZ EVN ;ZF=1,该数是偶数,转向“EVN” ODD: LEA DX, NO;否则,该数是奇数JMP DONE ;跳过程序“EVN” EVN: LEA DX, YES;该数是偶数 DONE:MOV AH, 9INT 21H ;输出该数的相关信息MOV AX, 4C00H,如果两个“平行”分支有相同的处理过程,可以把它们“合并” :,38,变量X取值93H,汇编、连接后运行该程序,程序输出:Its a odd number. 变量X取值9
19、4H,汇编、连接后运行该程序,程序输出:Its a even number.,39,DATA SEGMENT PROMPT DB 0DH, 0AH, “ Input a lowercase letter: $”;提示 ERR_MSG DB 0DH, 0AH, “ Input error . $”;输入错误警告 BUF DB 0DH, 0AH, Prev: ;输出缓冲区 PREV DB 20HDB 0DH, 0AH, Succ: SUCC DB 20HDB 0DH, 0AH, $ DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA,例4-3 从键盘上
20、输入一个小写字母,显示该字母的前导和后继。,40,START: MOV AX, DATAMOV DS, AX INPUT: LEA DX, PROMPTMOV AH, 9INT 21H ;输出提示信息MOV AH, 1INT 21H ;输入一个字符CMP AL, a ;输入正确性检查JB ERRORCMP AL, zJA ERRORMOV BL, AL ;计算“前导”字母DEC BL,41,CMP BL, aJB SKIP1 ;“前导”非字母,跳过MOV PREV, BL ;保存“前导”字母 SKIP1:INC AL ;计算“后继”字母CMP AL, zJA SKIP2 ;“后继”非字母,跳过
21、MOV SUCC, AL ;“后继”为字母,保存 SKIP2:LEA DX, BUF ;输出“前导”和“后继”字母MOV AH, 09HINT 21HJMP EXIT ;跳过出错处理程序,42,ERROR:LEA DX, ERR-MSG;显示出错信息MOV AH, 09HINT 21HJMP INPUT ;要求重新输入 EXIT:MOV AX, 4C00H ;返回OSINT 21H CODE ENDSEND START,健壮性 预设结果,程序要点:,43,例4-4 计算分段函数,INCLUDE YLIB.H DATA SEGMENT PROMPT DB 0DH, 0AH, “Input X (
22、 -10000+10000 ): $” X DW ? OUT_MSG DB 0DH, 0AH, “Y= $” DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATAMOV DS, AX ;装载DS,44,LEA DX, PROMPT ;输入提示信息CALL READINT ;从键盘上输入X的值MOV X, AX ;保存输入值 COMP:CMP X, 3 ;比较,X3 ?JG GREATER ;X3成立,转“GREATER”CMP X, -3 ;比较,X3 ?JL GREATER ;X3成立,转“GREATER”
23、LESS: ;|X|3 的程序段MOV BX, AX ;BXXSAL AX, 1 ;AX2XADD AX, BX ;AX2X+XSUB AX, 5 ;AX3X5JMP OUTPUT,45,GREATER: MOV AX, 6 ;|X|3 的程序段 OUTPUT:LEA DX, OUT_MSG ;结果的前导文字CALL WRITEINT ;输出计算结果CALL CRLF ;输出回车换行 EXIT: MOV AX, 4C00HINT 21H CODE ENDSEND START,46,复合逻辑表达式的分解,47,4.2.2 单分支选择结构,如果选择结构的一个分支为“空”,这样的程序流程称为 “单分
24、支选择结构”。 合理地选择Jcc指令所使用的条件,可以使程序更加流畅。 可以把一些基本选择结构程序改写为单分支选择结构。,48,例4-4为例,可以将Y“预设”为6,一旦条件|X|3成立,立即转向OUTPUT输出“预设”的结果,否则进行相应的计算。,49, COMP:MOV AX, 6 ;预设AX= 6CMP X, 3 ;比较,X3 ?JG OUTPUT ;若X3,转OUTPUT输出CMP X, -3 ;比较,X3 ?JL OUTPUT ;若X3,转OUTPUT输出 LESS: ;|X3 的程序段MOV AX, X ;AXX MOV BX, AX ;BXXSAL AX, 1 ;AX2XADD A
25、X, BX ;AX2X+XSUB AX, 5 ;AX3X5 OUTPUT:LEA DX, OUT_MSG ;结果的前导文字CALL WRITEINT ;输出计算结果,50,例4-5 将4位二进制转换成对应的十六进制字符,MOV AL, XCMP AL, 9JA ALPHADD AL, 30HJMP DONE ALPH:ADD AL, 37H DONE:MOV Y, AL,MOV AL, XOR AL, 30HCMP AL, 9JBE DONEADD AL, 7 DONE:MOV Y, AL,51,选择结构一个分支的程序中又出现了选择结构,这样的 结构称为“复合选择结构”或者“嵌套选择结构”。,
26、4.2.3 复合选择结构,排除法:每次判断排除若干可能,留下一种可能情况进行处理; 确认法:每次判断确认一种可能,对已确认的情况进行处理。,52,;方法a,逐项排除CMP X, 0JGE UN_MINUS MINUS:MOV Y, -1JMP DONE UN_MINUS:JE ZEROMOV Y, 1JMP DONE ZERO: MOV Y, 0 DONE: ,;方法b,逐项确认CMP X, 0JG PLUSJE ZERO MINUS:MOV Y, -1JMP DONE PLUS:MOV Y, 1JMP DONE ZERO:MOV Y, 0 DONE: ,例4-6 计算Y=SGN(X),53,
27、复合分支选择结构,54,4.2.4 多分支选择结构,在选择结构程序里,如果可供选择的程序块多于两个,这样的结构称为多分支选择结构,如下图 (a)所示,下图 (b)是汇编语言程序的实现方法。,55,DATA SEGMENT PROMPT DB 0DH, 0AH, “Input a number (13): $” MSG1 DB 0DH, 0AH, “FUNCTION 1 EXECUTED . $” MSG2 DB 0DH, 0AH, “FUNCTION 2 EXECUTED . $” MSG3 DB 0DH, 0AH, “FUNCTION 3 EXECUTED . $” DATA ENDS CO
28、DE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATAMOV DS, AX,例4-7 从键盘上输入数字“1”到“3”,根据输入选择对应程序 块执行。,56,INPUT:LEA DX, PROMPTMOV AH, 9INT 21H ;输出提示信息MOV AH, 1INT 21H ;输入一个数字CMP AL, 1JB INPUT ;“0”或非数字,重新输入JE F1 ;数字“1”,转F1CMP AL, 2JE F2 ;数字“2”,转F2CMP AL, 3JE F3 ;数字“3”,转F3JMP INPUT ;大于“3”,重新输入,57,F1:
29、 LEA DX, MSG1 ;F1程序块JMP OUTPUT F2: LEA DX, MSG2 ;F2程序块JMP OUTPUT F3: LEA DX, MSG3 ;F3程序块JMP OUTPUT OUTPUT:MOV AH, 9INT 21HMOV AX, 4C00HINT 21H CODE ENDSEND START,58,把完成各功能的程序块入口地址放在一张表格中,根据输入,计算出该功能程序块入口地址在表中的位置,通过存储器间接转移转入对应位置执行。,DATA SEGMENT PROMPT DB 0DH, 0AH, “Input a number (13): $” MSG1 DB 0DH
30、, 0AH, “FUNCTION 1 EXECUTED . $” MSG2 DB 0DH, 0AH, “FUNCTION 2 EXECUTED . $” MSG3 DB 0DH, 0AH, “FUNCTION 3 EXECUTED . $” ADDTBL DW F1, F2, F3 DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA,59,START:MOV AX, DATAMOV DS, AX INPUT:LEA DX, PROMPTMOV AH, 9INT 21H ;显示提示信息MOV AH, 1INT 21H ;输入一个数字CMP AL, 1
31、JB INPUT ;不正确输入,重新输入CMP AL, 3JA INPUT ;不正确输入,重新输入,60,SUB AL, 1 ;将数字字符“1”到“3”转换为0, 1, 2SHL AL, 1 ;转换为0,2,4MOV BL, ALMOV BH, 0 ;转入BXJMP ADDTBLBX;间接寻址,转移到对应程序块 F1: LEA DX, MSG1 ;F1程序块JMP OUTPUT F2: LEA DX, MSG2 ;F2程序块JMP OUTPUT F3: LEA DX, MSG3 ;F3程序块JMP OUTPUT ;这条指令可以省略,61,OUTPUT:MOV AH, 9INT 21HMOV A
32、X, 4C00HINT 21H CODE ENDSEND START,62,4.3 循环结构程序,4.3.1 循环指令 4.3.2 计数循环 4.3.3 条件循环 4.3.4 多重循环,63,循环结构也称为“重复结构”,它使得一组指令重复地执行,可以用有限长度的程序完成大量的处理任务,几乎所有的应用程序中都离不开循环结构。 循环一般由以下4个部分组成:,(1)初始化部分:为循环做准备,如累加器清零,设置地址指 针和计数器的初始值等。 (2)工作部分:实现循环的基本操作,也就是需要重复执行的 一段程序。 (3)修改部分:修改指针、计数器的值,为下一次循环做准备。 (4)控制部分:判断循环条件,结
33、束循环或继续循环。,64,计数循环:循环的次数事先已经知道,用一个变量(寄存器 或存储器单元)记录循环的次数(称为“循环计数 器”)。进行减法计数时,循环计数器的初值直接设为 循环次数,每循环一次将计数器减1,计数器减为0时, 循环结束。 条件循环:循环的次数事先并不确定,每次循环开始前或结 束后测试某个条件,根据这个条件是否满足来决定是 否继续下一次循环。,按照循环结束的条件,有以下两类循环:,65,按照循环结束判断在循环中的位置,有以下两种结构的循环:,WHILE循环:进入循环后,先判断循环结束条件,条件满足 则退出循环,循环次数最少为0次。 DO-WHILE循环:进入循环后,先执行工作部
34、分,然后判断循环 继续的条件,条件满足则转向工作部分继续循环,循环 次数最少1次。,66,67,LOOP Label ; CXCX-1,若(CX)0,转移到Label LOOPZ/LOOPE Label ; CXCX-1,若(CX)0且ZF=1,转移到Label LOOPNZ/LOOPNE Label ; CXCX-1,若(CX)0且ZF=0,转移到Label,4.3.1 循环指令,循环指令采用相对寻址方式,Label距离循环指令的下一条指令必须在-128+127B之内。,68,LOOPZ/LOOPE,LOOPNZ/LOOPNE指令的功能也可以由 Jcc指令实现。由于对CX先减1,后判断,如果
35、CX的初值为0,将循环 65536次。循环指令的执行不影响标志位。,LOOP指令的功能可以用Jcc指令实现:,DEC CX ; CXCX-1 JNZ Label ; 若(CX)0(也就是ZF=0),转移到Label,69,计数循环是基本的循环组织方式,用循环计数器的值来控制循环,有时候也可以结合其它条件共同控制。,4.3.2 计数循环,例4-8 从键盘上输入一个字符串(不超过80个字符),将它 逆序后输出。,INCLUDE YLIB.H DATA SEGMENT BUFFER DB 81, ?, 81 DUP(?) MESS DB 0AH, 0DH, “Input a string pleas
36、e : $” DATA ENDS,70,CODE SEGMENT ASSUME CS:CODE, DS:DATA START:MOV AX, DATAMOV DS, AXLEA DX, MESSMOV AH, 09HINT 21H ; 输出提示信息MOV AH, 0AHLEA DX, BUFFERINT 21H ; 输入字符串CALL CRLFLEA BX, BUFFER ; 缓冲区首地址送BXMOV CL, BUFFER+1MOV CH, 0 ; 输入字符个数送CX(循环次数),71,ADD BX, CXINC BX ; 计算字符串末地址送BX(指针) DISP: MOV DL, BXMOV
37、 AH, 02HINT 21H ; 逆序输出一个字符DEC BX ; 修改指针LOOP DISP ; 计数循环CALL CRLF ; 输出换行、回车,结束本行MOV AX, 4C00HINT 21H CODE ENDSEND START,72,INCLUDE YLIB.H DATA SEGMENT MESS1 DB 0AH, 0DH, “Input a number : $” MESS2 DB 0AH, 0DH, “The number in hexdecimal is: $” HEXTAB DB “0123456789ABCDEF” DATA ENDS CODE SEGMENT ASSUME
38、 CS: CODE, DS: DATA START: MOV AX, DATAMOV DS, AX,例4-9 从键盘上输入一个十进制无符号整数,将它用十六进 制格式输出。,73,LEA DX, MESS1CALL READDEC ; 输入一个十进制无符号数MOV SI, AX ; 转存在SI中LEA DX, MESS2MOV AH, 9INT 21H ; 输出文字前导MOV CX, 4 ; 循环次数初值LEA BX, HEXTAB; 换码表首地址 ONE: PUSH CXMOV CL, 4 ROL SI, CL ; 把最高4位移到最低4位,74,MOV AX, SI ; 转入AX中AND AX
39、, 000FH ; 保留最低4位XLAT ; 查表,转换成十六进制字符的ASCII代码MOV DL, ALMOV AH, 2 INT 21H ; 输出一个十六进制字符POP CXLOOP ONE ; 计数循环CALL CRLF ; 输出回车换行, 结束本行MOV AX, 4C00HINT 21H CODE ENDSEND START,75,用总分减去最高分、最低分,最后除以5,得到需要的成绩。求N个数据中最大值的方法: 预设一个“最大值”, 取出一个数据与这个“最大值”进行比较, 如果数据大于“最大值”,则将该数据作为新的“最大值”。 进行N次比较之后留下的就是这N个数据的最大值。预设的“最大
40、值”的初值可以从N个数据中任取一个,也可以根 据数据的范围,取一个该范围内的最小的数。计算最小值的方法与此类似。,例4-10 从键盘上输入七名裁判的评分(010),扣除一个最 高分,一个最低分,计算出其它五项评分的平均值(保留 一位小数),在显示器上输出。,76,INCLUDE YLIB.H DATA SEGMENT MESS1 DB 0DH, 0AH, “Input a score ( 010 ) : $” MESS2 DB 0DH, 0AH, “The final score is : $” C5 DB 5 MAX DB ? MIN DB ? SUM DB ? DATA ENDS CODE
41、 SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATAMOV DS, AX,77,MOV SUM, 0 ; 累加器清零MOV MAX, 0 ; “最大值”预设为0MOV MIN, 255 ; “最小值”预设为255MOV CX, 7 ; 循环计数器,初值7 ONE: LEA DX, MESS1CALL READDEC ; 键盘输入一个分数ADD SUM, AL ; 累加CMP MAX, AL ; 与“最大值”比较JA L1MOV MAX, AL ; 大于“最大值”则保留 L1: CMP MIN, AL ; 与“最小值”比较JB L2MOV
42、MIN, AL ; 小于“最小值”则保留 L2: LOOP ONE ; 计数循环,78,MOV AL, SUMSUB AL, MAXSUB AL, MIN ; 从总分中减去最大、最小值MOV SUM, ALXOR AH, AH ; 高8位清零DIV C5 ; 求平均值PUSH AX ; 保留余数(在AH中)MOV AH, 0 ; 清余数LEA DX, MESS2CALL WRITEDEC ; 输出结果的整数部分,79,MOV DL, .MOV AH, 2INT 21H ; 输出小数点POP AX ; 从堆栈弹出余数SHL AH, 1 ; 计算小数部分:(AH5)10=AH2MOV DL, AH
43、 ;OR DL, 30H ; 转换成ASCII代码MOV AH, 2INT 21H ; 输出结果的小数部分CALL CRLF ; 输出回车换行,结束本行MOV AX, 4C00HINT 21H CODE ENDSEND START,80,“稀疏矩阵”是指存在大量零元素的矩阵。为了节约存储空间,通常不存储那些值为零的元素。稀疏矩阵通常用一个“标尺”记录哪些位置上有非零元素。标尺RULE = 0001 0000 0010 0000B表示一个16个元素的 稀疏矩阵,它仅在第3,10位置上有非零元素,例4-11 求稀疏矩阵ARRAY非零元素的平均值。,81,.386 DATA SEGMENT USE1
44、6 ARRAY DW 123, -39, 211, ;稀疏矩阵非零元素 RULE DW 0001 0000 0011 0010B;“标尺” AVG DW ? ;非零元素的平均值 SUM DD ? ;累加器 DATA ENDS CODE SEGMENT USE16 ASSUME CS: CODE, DS: DATA START: MOV AX, DATAMOV DS, AX,82,LEA SI, ARRAY ;装载非零元素地址指针MOV CX, 16 ;设置计数器初值MOV BX, 0 ;设置非零元素个数计数器初值MOV SUM, 0 ;设置累加器初值 ONE: ROL RULE, 1 ;测试标
45、尺JNC NEXT ;该位置上为零元素,转NEXTMOVSX EAX, WORD PTRSI;取出一个元素,转换成32位有符号数ADD SUM, EAX ;累加INC BX ;统计非零元素个数ADD SI, 2 ;修改地址指针 NEXT:LOOP ONE ;计数循环控制,83,CMP BX, 0 ;有非零元素?JE EMPTY ;无非零元素,转向“EMPTY”MOV DX, WORD PTRSUM+2MOV AX, WORD PTRSUM ;取出32位累加值IDIV BX ;计算平均值MOV AVG, AX ;保存结果JMP EXIT EMPTY:MOV AVG, -1 ;无非零元素,置平均值
46、为-1 EXIT: MOV AX, 4C00HINT 21H CODE ENDS END START,84,4.3.3 条件循环,DATA SEGMENT STRING DB “A string for testing . ”, 0 LENTH DW ? DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START:MOV AX, DATAMOV DS, AX,例4-12 字符串STRING以代码0结束,求这个字符串的长度(字符个数)。,85,LEA SI, STRING ;装载字符串指针MOV CX, 0 ;设置计数器初值 TST: CMP B
47、YTE PTR SI, 0;比较JE DONE ;字符串结束,转向DONE保存结果INC SI ;修改指针INC CX ;计数JMP TST ;转向TST,继续循环 DONE:MOV LENTH, CX ;保存结果MOV AX, 4C00HINT 21H CODE ENDSEND START,86, TST: CMP BYTE PTR SI, 0 ;比较INC SI ;修改指针INC CX ;计数JNE TST ;转向TST,继续循环,错在哪里?运行结果会怎样?,87,LEA SI, STRING-1 ;装载字符串指针MOV CX, -1 ;装载计数器初值 TST: INC SI ;修改指针I
48、NC CX ;计数CMP BYTE PTR SI, 0 ;比较JNE TST ;未结束,转TST继续循环MOV LENTH, CX ;字符串结束,保存结果,比较一下,您喜欢这种风格吗?,88,DATA SEGMENT ARRAY DW 1, 2, 3, 4, 5, 6, -1 AVRG DW ? DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATAMOV DS, AX,例4-13 一维无符号字数组ARRAY以-1作为数组结束标志, 求这个数组各元素的平均值。,89,LEA BX, ARRAY ;装载数组指针XO
49、R CX, CX ;设置计数器初值XOR DX, DXXOR AX, AX ;清累加器 ONE: CMP WORD PTRBX, -1;判数组是否结束JE DONE ;数组结束,转DONE,结束处理ADD AX, BX ;累加ADC DX, 0 ;保留进位ADD BX, 2 ;修改指针INC CX ;数组元素个数计数JMP ONE,90,DONE: JCXZ NULL ;数组元素个数为0, 不能求平均值DIV CX ;计算数组平均值MOV AVRG, AX ;保存结果JMP EXIT NULL: MOV AVRG, -1 ;数组为“空”,记平均值为-1 EXIT: MOV AX, 4C00HINT 21H CODE ENDSEND START,