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 条件转移指令 54.1.1 无条件转移指令无条件转移指令n只要执行无条件转移指令只要执行无条件转移指令JMP,就使程序转,就使程序转到指定的目标地址处,从目标地址处开始执到指定的目标地址处,从目标地址处开始执行那里的指令行那里的指令n操作数操作数label是要转移到的是要转移到的目标地址目标地址(目的目的地址地址、转移地址转移地址)nJMP指令分成指令分成4种类型:种类型:段内转移、直接寻址段内转移、直接寻址 段内转移、间接寻址段内转移、间接寻址 段间转移
3、、直接寻址段间转移、直接寻址 段间转移、间接寻址段间转移、间接寻址JMP label;程序转向label标号指定的地址JMP6目标地址的寻址方式目标地址的寻址方式n直接寻址方式直接寻址方式n转移地址象立即数一样,直接在指令的转移地址象立即数一样,直接在指令的机器代码中,就是直接寻址方式机器代码中,就是直接寻址方式n间接寻址方式间接寻址方式n转移地址在寄存器或主存单元中,就是转移地址在寄存器或主存单元中,就是通过寄存器或存储器的间接寻址方式通过寄存器或存储器的间接寻址方式用标号表达用寄存器或存储器操作数表达JMP7目标地址的范围:段内(近程)目标地址的范围:段内(近程)n段内转移段内转移短转移(
4、短转移(short)n转移范围可以用一个字节表达,在段转移范围可以用一个字节表达,在段内内128127范围的转移范围的转移n段内转移段内转移近转移(近转移(near)n在当前代码段在当前代码段64KB范围内转移范围内转移(32KB范围)范围)n不需要更改不需要更改CS段地址,段地址,只要改变只要改变IP偏移地址偏移地址代码段代码段代码段代码段JMP8目标地址的范围:段间(远程)目标地址的范围:段间(远程)n段间转移段间转移远转移(远转移(far)n从当前代码段跳转到另一个代码从当前代码段跳转到另一个代码段,可以在段,可以在1MB范围范围n需要需要更改更改CS段地址和段地址和IP偏移地址偏移地址
5、n目标地址必须用一个目标地址必须用一个32位数表达,位数表达,叫做叫做32位远指针位远指针,它就是逻辑地,它就是逻辑地址址代码段代码段 实际编程时,汇编程序会根据目标地址的距离,自动处理成短转移、近转移或远转移 程序员可用操作符short、near ptr 或ar ptr 强制JMP9JMP段内转移、直接寻址段内转移、直接寻址JMP labelJMP label;IPIP+IPIP+位移量位移量n位移量是紧接着位移量是紧接着JMP指令后的那条指令的偏移地址到目标指令后的那条指令的偏移地址到目标指令的偏移地址的地址位移指令的偏移地址的地址位移n当向地址增大方向转移时,位移量为正;向地址减小方向当
6、向地址增大方向转移时,位移量为正;向地址减小方向转移时,位移量为负转移时,位移量为负jmp jmp againagain;转移到;转移到againagain处继续执行处继续执行again:again:dec cxdec cx;标号;标号againagain的指令的指令jmp jmp outputoutput;转向;转向outputoutputoutput:output:mov result,almov result,al;标号;标号outputoutput的指令的指令实际为相对寻址10段内转移、间接寻址段内转移、间接寻址JMP r16/m16 JMP r16/m16;IPr16/m16IPr1
7、6/m16n将一个将一个1616位寄存器或主存字单元内容送入位寄存器或主存字单元内容送入IPIP寄存器,作为新的指令指针,但不修改寄存器,作为新的指令指针,但不修改CSCS寄存寄存器的内容器的内容jmp axjmp ax;IPAXIPAXjmp word ptr 2000hjmp word ptr 2000h;IP2000hIP2000hJMPJMP111)JMP ONE;近程直接转移2)LEA DX,ONE JMP DX;寄存器间接段内转移3)LEA BX,TARGET JMP WORD PTRBX ;存储器间接段内转移4)JMP TARGET;存储器间接段内转移已在数据段定义存储器单元“T
8、ARGET”:TAEGETDW ONE下面四组指令都可以实现向标号“ONE”的转移:12段间转移、直接寻址段间转移、直接寻址JMP far ptr labelJMP far ptr label;IPlabelIPlabel的偏移地址的偏移地址;CSlabelCSlabel的段地址的段地址n将标号所在段的段地址作为新的将标号所在段的段地址作为新的CS值,值,标号在该段内的偏移地址作为新的标号在该段内的偏移地址作为新的IP值;这值;这样,程序跳转到新的代码段执行样,程序跳转到新的代码段执行jmp far ptr othersegjmp far ptr otherseg;远转移到代码段;远转移到代码
9、段2 2的的othersegothersegJMP13段间转移、间接寻址段间转移、间接寻址JMP far ptr memJMP far ptr mem;IPmemIPmem,CSmem+2CSmem+2n用一个双字存储单元表示要跳转的目标地用一个双字存储单元表示要跳转的目标地址。这个目标地址存放在主存中连续的两个址。这个目标地址存放在主存中连续的两个字单元中的,低位字送字单元中的,低位字送IPIP寄存器,高位字送寄存器,高位字送CSCS寄存器寄存器mov word ptr bx,0mov word ptr bx,0mov word ptr bx+2,1500hmov word ptr bx+2
10、,1500hJMP far ptr bx JMP far ptr bx ;转移到;转移到1500h:01500h:0JMP141)JMP AR PTR TWO;远程直接转移2)LEA BX,AR_TGT JMP DWORD PTRBX;远程间接转移3)JMP AR_TGT;远程间接转移假设已在数据段定义存储器单元“AR_TGT”如下:AR_TGTDDTWO下面三组指令都可以实现向远程标号“TWO”的转移:154.1.2 比较和测试指令(1)CMP(Compare,比较)指令指令格式:CMP目的操作数,源操作数目的操作数:8位/16位/32位的寄存器/存储器操作数。源操作数:与目的操作数同类型的
11、寄存器/存储器/立即数。功能:目的操作数-源操作数,保留运算产生的标志位,不保留运算的差。用来比较两个有符号数或无符号数的大小。16假设(CX)=0A0B0H,指令“CMP CX,0”执行后:Z=0 (CX)0 O=0 减法操作没有产生溢出(S是正确的结果符号位)S=1 如果CX中存放的是有符号数,这个数是负数 C=0 如果CX中存放的是无符号数,这个数大于0这条指令与下面的指令等效:ORCX,0 ;根据CX的值确定S,Z AND CX,0H;根据CX的值确定S,Z XOR CX,0 ;根据CX的值确定S,Z17C=0,目的操作数源操作数C=1,目的操作数源操作数对于有符号数:O=0时,S为正
12、确的结果符号 O=1时,S与正确的符号位相反 O S的运算结果反映了正确的结果符号O S=0,目的操作数源操作数O S=1,目的操作数源操作数对于无符号数:18Z=0(X)5O=1 减法操作产生溢出,S是错误的结果符号位S=0 O S=1,目的操作数源操作数如果X中存放的是有符号数,X5(由于Z=0,所以不相等)例:假设存储器变量(X)=80H,指令“CMP X,5”执行后:19指令格式:TEST 目的操作数,源操作数目的操作数:8位/16位/32位的寄存器/存储器操作数。源操作数:与目的操作数同类型的寄存器/存储器/立即数。功能:TEST指令将目的操作数与源操作数进行逻辑乘运算,保留运算产生
13、的各标志位,但是不保留逻辑乘的结果。该指令用来测试目的操作数中某几位二进制的特征。(2)TEST(Test,测试)指令,测试)指令20如果Z=0,说明BL寄存器的D2D100,这两位为01,10或11。如果Z=1,说明BL寄存器的D2D100,这两位为00。指令 TESTVAR,1 执行后:如果Z=0,说明变量VAR的D0位为1,该数为奇数如果Z=1,说明变量VAR的D0位为0,该数为偶数指令 TESTBL,6 执行后:214.1.3 条件转移指令 “J”是条件转移指令操作码的第一个字母 “cc”是代表转移条件的13个字母 “label”是转移目的地的标号。对于16位80X86CPU,条件转移
14、指令的转移范围在下一条指令地址128127字节之间。条件转移指令格式:Jcclabel22两个有符号数的比较结果通过O,S,Z反映出来 G(Greater,大于)L(Less,小于)E(Equal,等于)N(Not,否)例:JG/JNLE 大于(不小于等于)则转移 JNL/JGE 不小于(大于或等于)则转移 JE/JZ等于(为零)则转移(1)有符号数比较的条件转移指令)有符号数比较的条件转移指令23指令助记符指令助记符 指令功能指令功能转移条件转移条件JG,JNLE大于(不小于等于)时转移大于(不小于等于)时转移OFSF=0且且ZF=0JGE,JNL大于等于(不小于)时转移大于等于(不小于)时
15、转移OFSF=0JZ,JE为零(相等)时转移为零(相等)时转移ZF=1JNZ,JNE不为零(不相等)时转移不为零(不相等)时转移ZF=0JL,JNGE小于(不大于等于)时转移小于(不大于等于)时转移OFSF=1JLE,JNG小于等于(不大于)时转移小于等于(不大于)时转移OFSF=1或或ZF=1根据有符号数大小的条件转移指令根据有符号数大小的条件转移指令24 MOV AX,X ;取出X的值送AX CMP AX,Y ;比较两个操作数,建立需要的标志位 JG GREATER;如果XY,转移到“GREATER”处执行 JE EQUAL;如果X=Y,转移到“EQUAL”处执行LESS:;否则,执行标号
16、“LESS”处的指令GREATER:EQUAL:根据有符号字变量根据有符号字变量X和和Y的大小的程序分支的大小的程序分支25SUBAX,BX;AX(AX)(BX),建立标志位JGESKIP;如果(AX)0,转标号“SKIP”NEGAX;如果(AX)0,把AX的值取反SKIP:JG GREATER;如果XY,转移到“GREATER”处 JE EQUAL;如果X=Y,转移到“EQUAL”处 JL LESS;如果XY,转移到“LESS”处LESS:下面程序能够正确运行,但最后一条指令有“画蛇添足”之嫌。下面的程序计算 AX=|AXBX|例例18:比较有符号数:比较有符号数cmp ax,bxcmp a
17、x,bx;比较;比较axax和和bxbxjnl nextjnl next;若;若axaxbxbx,转移,转移xchg ax,bxxchg ax,bx;若;若axaxbxbx,交换,交换next:next:.结果:AX保存较大的有符号数27求求N个数的最大值个数的最大值n求求N N个数据中最大值的方法:个数据中最大值的方法:预设一个预设一个“最大值最大值”,取出一个数据与这个取出一个数据与这个“最大值最大值”进行进行比较,如果数据大于比较,如果数据大于“最大值最大值”,则将该,则将该数据作为新的数据作为新的“最大值最大值”。进行进行N N次比较之后留下的就是这次比较之后留下的就是这N N个数个数
18、据的最大值。据的最大值。n 预设的预设的“最大值最大值”的初值可以从的初值可以从N N个数个数据中任取一个,也可以根据数据的范围,据中任取一个,也可以根据数据的范围,取一个该范围内的最小的数。取一个该范围内的最小的数。28例:求例:求5个带符号数的最大值个带符号数的最大值 MOV CX,4 LEA BX,NUM MOV AL,BXNEXT:INC BX CMP AL,BX JG NEXT1 MOV AL,BXNEXT1:LOOP NEXT29两个有符号数的比较结果通过C,Z反映出来,代表转移条件的字母:A(Above,高于)B(Below,低于)E(Equal,等于)(2)无符号数比较的条件转
19、移指令)无符号数比较的条件转移指令30指令助记符指令助记符指令功能指令功能转移条件转移条件JA,JNBE高于(不低于等于)时转移高于(不低于等于)时转移CF=0且且ZF=0JAE,JNB,JNC高于等于(不低于)时转移高于等于(不低于)时转移CF=0JZ,JE为零(相等)时转移为零(相等)时转移ZF=1JNZ,JNE不为零(不相等)时转移不为零(不相等)时转移ZF=0JB,JNAE,JC低于(不高于等于)时转移低于(不高于等于)时转移CF=1JBE,JNA低于等于(不高于)时转移低于等于(不高于)时转移CF=1或或ZF=1根据无符号数大小的条件转移指令根据无符号数大小的条件转移指令31(3)根
20、据单个标志位的条件转移指令)根据单个标志位的条件转移指令n这组指令单独判断这组指令单独判断5个状态标志之一个状态标志之一JZ/JE和和JNZ/JNE:利用零标志:利用零标志ZF,判断结果,判断结果是否为零(或相等)是否为零(或相等)JS和和JNS:利用符号标志:利用符号标志SF,判断结果是正是,判断结果是正是负负JO和和JNO:利用溢出标志:利用溢出标志OF,判断结果是否产,判断结果是否产生溢出生溢出JP/JPE和和JNP/JPO:利用奇偶标志:利用奇偶标志PF,判断,判断结果中结果中“1”的个数是偶是奇的个数是偶是奇JC/JB/JNAE和和JNC/JNB/JAE:利用进位标:利用进位标志志C
21、F,判断结果是否进位或借位,判断结果是否进位或借位Jcc例题12例题13例题14例题15例题16例例12:JZ/JNZ指令指令test al,80htest al,80h;测试最高位;测试最高位jz next0jz next0;D7D70 0(ZFZF1 1),转移),转移mov ah,0ffhmov ah,0ffh;D7D71 1,顺序执行,顺序执行jmp donejmp done;无条件转向;无条件转向next0:next0:mov ah,0mov ah,0done:done:.test al,80htest al,80h;测试最高位;测试最高位jnz next1jnz next1;D7D
22、71 1(ZFZF0 0),转移),转移mov ah,0mov ah,0;D7D70 0,顺序执行,顺序执行jmp donejmp done;无条件转向;无条件转向next1:next1:mov ah,0ffhmov ah,0ffhdone:done:.例例13:JS/JNS指令指令;计算计算|XY|(绝对值)(绝对值);X和和Y为存放于为存放于X单元和单元和Y单元的单元的16位操作数位操作数;结果存入;结果存入resultmov ax,Xmov ax,Xsub ax,Ysub ax,Yjns nonnegjns nonnegneg axneg ax;negneg是求补指令是求补指令nonne
23、g:nonneg:mov result,axmov result,ax例例14:JO/JNO指令指令;计算;计算XY;X和和Y为存放于为存放于X单元和单元和Y单元的单元的16位操作数位操作数;若溢出,则转移到;若溢出,则转移到overflow处理处理mov ax,Xmov ax,Xsub ax,Ysub ax,Yjo overflowjo overflow.;无溢出,结果正确;无溢出,结果正确overflow:overflow:.;有溢出处理;有溢出处理例例15:JP/JNP指令指令;设字符的;设字符的ASCII码在码在AL寄存器中寄存器中;将字符加上奇校验位;将字符加上奇校验位;在字符;在字
24、符ASCII码中为码中为“1”的个数已为奇数时的个数已为奇数时;则令其最高位为;则令其最高位为“0”;否则令最高位为;否则令最高位为“1”and al,7fhand al,7fh;最高位置;最高位置“0”0”,同时判断,同时判断“1”1”的个的个数数jnp nextjnp next;个数已为奇数,则转向;个数已为奇数,则转向nextnextor al,80hor al,80h;否则,最高位置;否则,最高位置“1”1”next:next:.例例16:JC/JNC指令指令;记录;记录BX中中1的个数的个数xor al,alxor al,al;ALAL0 0,CFCF0 0again:again:t
25、est bx,test bx,0ffffh 0ffffh;等价于;等价于 cmp bx,0cmp bx,0je nextje nextshl bx,1shl bx,1jnc againjnc againinc alinc aljmp againjmp againnext:next:.;ALAL保存保存1 1的个数的个数另一种做法记录记录BX中中“1”的个数的个数xor al,alxor al,al;ALAL0 0,CFCF0 0again:again:cmp bx,0cmp bx,0jz nextjz nextshl bx,1shl bx,1;也可使用;也可使用 shr bx,1shr bx,
26、1adc al,0adc al,0jmp againjmp againnext:next:.;ALAL保存保存1 1的个数的个数38JNGSkipJMPLabelSkip:对于32位80X86CPU,可以实现64KB范围内的转移。JG Label ;如果标号“Label”超出范围,汇编时将出错可以把上面指令修改为:如果转移地址超出范围如果转移地址超出范围39指令格式:JCXZLabel;若CX=0,转移到Label JECXZLabel;若ECX=0,转移到Label它们的转移范围固定为下一条指令地址128127字节以内。(4)根据)根据CX/ECX寄存器值的条件转移指令寄存器值的条件转移指令
27、404.2 选择结构程序4.2.1 基本选择结构4.2.2 单分支选择结构4.2.3 复合选择结构4.2.4 多分支选择结构41 为“|X|3”和“|X|3”分别编制了进行不同处理的指令序列。如果条件“|X|3”成立(为“真”),执行“Y=3X5”如果条件“|X|3”不成立(为“假”),执行Y=6 通过在不同的程序之间进行选择,实现程序的不同功能,“选择结构”因此得名。653XY33XX计算分段函数的值424.2.1 基本选择结构43CODESEGMENTASSUMECS:CODESTART:JMPBEGINXDB?;被测试的数,汇编之前置入YESDB0AH,0DH,“Its a even n
28、umber.”,0AH,0DH,$NODB0AH,0DH,“Its a odd number.”,0AH,0DH,$BEGIN:PUSHCSPOPDS例4-2 判断变量X的值是否为“偶数”44TEST X,1;测试X的最低位,确定是否为偶数JZEVN;Z=1,该数是偶数,转向“EVN”ODD:LEADX,NO;否则,该数是奇数MOV AH,9INT21H;输出奇数的相关信息JMPDONE;跳过程序“EVN”EVN:LEADX,YESMOV AH,9INT21H;输出偶数的相关信息DONE:MOV AX,4C00HINT21HCODEENDSENDSTART45TEST X,1;测试X的最低位,
29、确定是否为偶数JZEVN;Z=1,该数是偶数,转向“EVN”ODD:LEA DX,NO;否则,该数是奇数JMP DONE;跳过程序“EVN”EVN:LEA DX,YES;该数是偶数DONE:MOV AH,9INT21H;输出该数的相关信息MOV AX,4C00H如果两个“平行”分支有相同的处理过程,可以把它们“合并”:46变量X取值93H,汇编、连接后运行该程序,程序输出:Its a odd number.变量X取值94H,汇编、连接后运行该程序,程序输出:Its a even number.47附例附例1:显示:显示BX的最高位的最高位shl bx,1;BX最高位移入最高位移入CF标志标志j
30、c one;CF1,即最高位为,即最高位为1,转移,转移mov dl,30h;CF0,即最高位为,即最高位为0:DL30H0jmp two;一定要跳过另一个分支体;一定要跳过另一个分支体one:mov dl,31h;DL 31H1two:mov ah,2int 21h;显示;显示可以用JNC替换JC48附例附例1:显示:显示BX的最高位(另解的最高位(另解1)shl bx,1;BX最高位移入最高位移入CF标志标志jnc one;CF0,即最高位为,即最高位为0,转移,转移mov dl,31h;CF1,即最高位为,即最高位为1:DL31H1jmp two;一定要跳过另一个分支体;一定要跳过另一个
31、分支体one:mov dl,30h;DL 30H0two:mov ah,2int 21h;显示;显示转换为单分支结构49附例附例1:显示:显示BX的最高位(另解的最高位(另解2)mov dl,0;DL30H0shl bx,1;BX最高位移入最高位移入CF标志标志jnc two;CF0,即最高位为,即最高位为0,转移,转移mov dl,1;CF1,即最高位为,即最高位为1:DL31H1two:mov ah,2int 21h;显示;显示 编写分支程序,需留心分支的开始和结束50附例附例1:显示:显示BX的最高位(无分支)的最高位(无分支)mov dl,0shl bx,1;BX最高位移入最高位移入C
32、F标志标志adc dl,30h;CF0,DL030h030H0;CF1,DL030h131H1two:mov ah,2int 21h;显示;显示51DATASEGMENTPROMPT DB 0DH,0AH,“Input a lowercase letter:$”;提示ERR_MSG DB 0DH,0AH,“Input error.$”;输入错误警告BUDB 0DH,0AH,Prev:;输出缓冲区PREVDB 20HDB 0DH,0AH,Succ:SUCCDB 20HDB 0DH,0AH,$DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA例4-3 从键盘上输入一个
33、小写字母,显示该字母的前导和后继。52START:MOV AX,DATAMOV DS,AXINPUT:LEADX,PROMPTMOV AH,9INT21H;输出提示信息MOV AH,1INT21H;输入一个字符CMPAL,a;输入正确性检查JBERRORCMPAL,zJAERRORMOV BL,AL;计算“前导”字母DECBL53CMPBL,aJBSKIP1;“前导”非字母,跳过MOV PREV,BL;保存“前导”字母SKIP1:INCAL;计算“后继”字母CMPAL,zJASKIP2;“后继”非字母,跳过MOV SUCC,AL;“后继”为字母,保存SKIP2:LEADX,BU;输出“前导”和
34、“后继”字母MOV AH,09HINT21HJMPEXIT;跳过出错处理程序MOV PREV,ALJMP SKIP3SKIP1:MOV PREV,20HSKIP3:INC AL54ERROR:LEA DX,ERR-MSG;显示出错信息MOV AH,09HINT21HJMPINPUT;要求重新输入EXIT:MOV AX,4C00H;返回OSINT21HCODEENDSENDSTART健壮性预设结果程序要点:55例4-4 计算分段函数 653XY33XXINCLUDEYLIB.HDATASEGMENTPROMPTDB0DH,0AH,“Input X(-10000+10000):$”XDW?OUT_
35、MSGDB0DH,0AH,“Y=$”DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX;装载DS56LEADX,PROMPT;输入提示信息CALL READINT;从键盘上输入X的值MOV X,AX;保存输入值COMP:CMP X,3;比较,X3?JGGREATER ;X3成立,转“GREATER”CMPX,-3;比较,X3?JLGREATER ;X3 的程序段OUTPUT:LEA DX,OUT_MSG;结果的前导文字CALL WRITEINT;输出计算结果CALL CRL;输出回车换行EXIT:MOV AX,
36、4C00HINT 21HCODEENDSEND START58复合逻辑表达式的分解594.2.2 单分支选择结构 如果选择结构的一个分支为“空”,这样的程序流程称为“单分支选择结构”。合理地选择Jcc指令所使用的条件,可以使程序更加流畅。可以把一些基本选择结构程序改写为单分支选择结构。60计算AX|AX|的两种判断方法:61 COMP:MOV AX,6;预设AX=6CMP X,3;比较,X3?JG OUTPUT;若X3,转OUTPUT输出CMP X,-3;比较,X3?JL OUTPUT;若X3成立,立即转向OUTPUT输出“预设”的结果,否则进行相应的计算。62例4-5 将4位二进制转换成对应
37、的十六进制字符 HXHXY373099XX MOV AL,X CMPAL,9 JAALPH ADDAL,30H JMPDONEALPH:ADDAL,37HDONE:MOV Y,ALMOV AL,X ORAL,30H CMPAL,9 JBEDONE ADDAL,7DONE:MOV Y,AL63 选择结构一个分支的程序中又出现了选择结构,这样的结构称为“复合选择结构”或者“嵌套选择结构”。4.2.3 复合选择结构排除法:每次判断排除若干可能,留下一种可能情况进行处理;确认法:每次判断确认一种可能,对已确认的情况进行处理。64例4-6 计算Y=SGN(X);方法a,逐项排除 CMPX,0 JGEUN
38、_MINUSMINUS:MOVY,-1 JMPDONEUN_MINUS:JEZERO MOVY,1 JMPDONEZERO:MOVY,0DONE:;方法b,逐项确认 CMPX,0 JGPLUS JEZEROMINUS:MOVY,-1 JMPDONEPLUS:MOVY,1 JMPDONEZERO:MOVY,0DONE:复合分支选择结构复合分支选择结构654.2.4 多分支选择结构在选择结构程序里,如果可供选择的程序块多于两个,这样的结构称为多分支选择结构,如下图(a)所示,下图(b)是汇编语言程序的实现方法。66DATASEGMENTPROMPTDB0DH,0AH,“Input a number
39、(13):$”MSG1 DB0DH,0AH,“UNCTION 1 EXECUTED.$”MSG2 DB0DH,0AH,“UNCTION 2 EXECUTED.$”MSG3 DB0DH,0AH,“UNCTION 3 EXECUTED.$”DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOV AX,DATAMOV DS,AX例4-7 从键盘上输入数字“1”到“3”,根据输入选择对应程序 块执行。67INPUT:LEADX,PROMPTMOV AH,9INT21H;输出提示信息MOV AH,1INT21H;输入一个数字CMPAL,1JBINPUT;“0”
40、或非数字,重新输入JE1;数字“1”,转1CMPAL,2JE2;数字“2”,转2CMPAL,3JE3;数字“3”,转3JMPINPUT;大于“3”,重新输入681:LEADX,MSG1;1程序块JMPOUTPUT2:LEADX,MSG2;2程序块JMPOUTPUT3:LEADX,MSG3;3程序块JMPOUTPUTOUTPUT:MOV AH,9INT21HMOV AX,4C00HINT21HCODEENDSENDSTART 69DATASEGMENT PROMPTDB 0DH,0AH,“Input a number(13):$”MSG1DB 0DH,0AH,“UNCTION 1 EXECUTE
41、D.$”MSG2DB 0DH,0AH,“UNCTION 2 EXECUTED.$”MSG3DB 0DH,0AH,“UNCTION 3 EXECUTED.$”ADDTBLDW 1,2,3DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA用地址表实现多分支用地址表实现多分支70START:MOV AX,DATAMOV DS,AXINPUT:LEADX,PROMPTMOV AH,9INT21H;显示提示信息MOV AH,1INT21H;输入一个数字CMPAL,1JBINPUT;不正确输入,重新输入CMPAL,3JAINPUT;不正确输入,重新输入71SUBAL,1;将数
42、字字符“1”到“3”转换为0,1,2SHLAL,1;转换为0,2,4MOV BL,ALMOV BH,0;转入BXJMPADDTBLBX;间接寻址,转移到对应程序块1:LEADX,MSG1;1程序块JMPOUTPUT2:LEADX,MSG2;2程序块JMPOUTPUT3:LEADX,MSG3;3程序块JMPOUTPUT;这条指令可以省略72OUTPUT:MOV AH,9INT21HMOV AX,4C00HINT21HCODEENDSENDSTART734.3 循环结构程序4.3.1 循环指令4.3.2 计数循环4.3.3 条件循环4.3.4 多重循环74循环结构也称为“重复结构”,几乎所有的应用
43、程序中都离不开循环结构。循环一般由以下4个部分组成:(1)初始化部分:为循环做准备,如累加器清零,设置地址指针和计数器的初始值等。(2)工作部分:实现循环的基本操作,也就是需要重复执行的一段程序。(3)修改部分:修改指针、计数器的值,为下一次循环做准备。(4)控制部分:判断循环条件,结束循环或继续循环。75计数循环:循环的次数事先已知,用一个变量(寄存器或存储器单元)记录循环的次数(称为“循环计数器”)。条件循环:循环的次数事先并不确定,每次循环开始时或结束后测试某个条件,根据这个条件是否满足来决定是否继续下一次循环。按照循环结束的条件,有以下两类循环:76两种结构的循环:WHILE循环:进入
44、循环后,先判断循环结束条件,条件满足则退出循环,循环次数最少为0次。DO-WHILE循环:进入循环后,先执行工作部分,然后判断循环继续的条件,条件满足则转向工作部分继续循环,循环次数最少1次。7778LOOPLabel;CXCX-1,若(CX)0,转移到LabelLOOPZ/LOOPE Label;CXCX-1,若(CX)0且Z=1,转移到LabelLOOPNZ/LOOPNELabel;CXCX-1,若(CX)0且Z=0,转移到Label4.3.1 循环指令循环指令采用相对寻址方式,Label距离循环指令的下一条指令必须在-128+127B之内。79 LOOPZ/LOOPE,LOOPNZ/LO
45、OPNE指令的功能也可以由Jcc指令实现。由于对CX先减1,后判断,如果CX的初值为0,将循环65536次。循环指令的执行不影响标志位。LOOP指令的功能可以用Jcc指令实现:DECCX;CXCX-1JNZLabel;若(CX)0(也就是Z=0),转移到Label804.3.2 计数循环计数循环n计数控制循环计数控制循环利用利用循环次数循环次数作为控制条件作为控制条件n易于采用循环指令易于采用循环指令LOOP和和JCXZ实现实现n初始化:将循环次数或最大初始化:将循环次数或最大循环次数置入循环次数置入CXn循环体循环体n循环控制:用循环控制:用LOOP指令对指令对CX减减1、并判断是否为、并判
46、断是否为081附例附例2:用二进制显示:用二进制显示BL内容内容mov cx,8;CX8(循环次数)(循环次数)again:shl bl,1;左移进;左移进CF,从高位开始显示从高位开始显示mov dl,0;MOV指令不改变指令不改变CFadc dl,30h;DL030HCF;CF若是若是0,则,则DL 0;CF若是若是1,则,则DL 1 mov ah,2int 21h;显示;显示loop again;CX减减1,如果,如果CX未减至未减至0,则循环,则循环计数控制循环先循环后判断82例4-8 从键盘上输入一个字符串(不超过80个字符),将它逆序后输出。INCLUDEYLIB.HDATASEG
47、MENTBUER DB81,?,81 DUP(?)MESSDB0AH,0DH,“Input a string please:$”DATAENDS83CODESEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATAMOV DS,AXLEADX,MESSMOV AH,09HINT21H;输出提示信息MOV AH,0AHLEADX,BUERINT21H;输入字符串CALL CRLLEABX,BUER;缓冲区首地址送BXMOV CL,BUER+1MOV CH,0;输入字符个数送CX(循环次数)84ADDBX,CXINCBX;计算字符串末地址送BX(指针)DISP:M
48、OV DL,BXMOV AH,02HINT21H;逆序输出一个字符DECBX;修改指针LOOP DISP;计数循环CALL CRL;输出换行、回车,结束本行MOV AX,4C00HINT21HCODEENDSENDSTART85附例附例3:求数组元素的最大值和最小值:求数组元素的最大值和最小值;数据段数据段arraydw 10;假设一个数组,其中头个数据;假设一个数组,其中头个数据10表示元素个数表示元素个数dw-3,0,20,900,587,-632,777,234,-34,-56;这是一个有符号字量元素组成的数组;这是一个有符号字量元素组成的数组maxay dw?;存放最大值;存放最大值m
49、inay dw?;存放最小值;存放最小值初始化:循环次数元素个数1循环体:逐个比较求最大、小值循环控制:比较完所有数据86附例附例3:代码段:代码段;代码段;代码段lea si,arraymov cx,si;取得元素个数;取得元素个数dec cx;减;减1后是循环次数后是循环次数add si,2mov ax,si;取出第一个元素给;取出第一个元素给AX,AX用于暂存最大值用于暂存最大值mov bx,ax;取出第一个元素给;取出第一个元素给BX,BX用于暂存最小值用于暂存最小值初始化87附例附例3:代码段(续):代码段(续)maxck:add si,2cmp si,ax;与下一个数据比较;与下一
50、个数据比较jle minckmov ax,si;AX取得更大的数据取得更大的数据jmp nextminck:cmp si,bxjge nextmov bx,si;BX取得更小的数据取得更小的数据next:loop maxck;计数循环;计数循环mov maxay,ax;保存最大值;保存最大值mov minay,bx;保存最小值;保存最小值循环体88INCLUDEYLIB.HDATASEGMENTMESS1DB0AH,0DH,“Input a number:$”MESS2DB0AH,0DH,“The number in hexdecimal is:$”HEXTABDB“0123456789ABC