第4章分支与循环程序设计第4章分支与循环程序设计4.1条件标志位的设置规则4.2跳转类指令4.3分支程序设计4.4循环程序设计习题四第4章分支与循环程序设计4.1条件标志位的设置规则4.1.1CF──进位和借位标志CF主要用于记载两个数据相加或相减时,最高位向外的进位或借位情况,如果有进位或借位则CF被置1,否则置0。参与运算的数据可以是16位的,也可以是8位的。第4章分支与循环程序设计【例4.1】设AX=78C4H,BX=9F35H,判断下列指令执行后CF的值。(1)ADDAX,BX(2)ADDAH,AL(3)ADDAH,BL(4)SUBAX,BX(5)SUBBX,BX(6)SUBAH,BH第4章分支与循环程序设计【解】(1)0111,1000,1100,0100+1001,1111,0011,0101────────────1,0001,0111,1111,1001(2)0111,1000+1100,0100───────1,0011,1100最左边的1是b7位向前的进位,故CF被置1。计算结果有17位,最左边的1是b15位(以最右边一位为b0位,依次向左,最高位是b15位)向前的进位,故CF被置1。第4章分支与循环程序设计(3)0111,1000+0011,0101───────1010,1101b7位向前没有进位,故CF被清0。(4)0111,1000,1100,0100-1001,1111,0011,0101────────────1,1101,1001,1000,1111最左边的1表示不够减,b15位需要向前借位,故CF被置1。第4章分支与循环程序设计(5)1001,1111,0011,0101-1001,1111,0011,0101────────────0000,0000,0000,0000虽然相减结果为0,却也是够减的情况,故CF被置0。(6)0111,1000-1001,1111───────1,1101,1001最左边的1表示不够减,第7位需要向前借位,故CF被置1。第4章分支与循环程序设计注意例4.1中并没有提及各数据是无符号数还是带符号数,不论编程人员对数据如何看待,ALU在加减运算设置CF时都是当作无符号数处理的。实质上,CF中记载了加法运算最高位向前的进位值(无进位可视为进0),或者是减法运算的借位值(不需要借位可视为借0)对于两个无符号数,如果相减后CF的值是1,表示不够减,当然就有“被减数小于减数”的结论;反之相减后CF为0则表示够减,可知“被减数大于或等于减数”。第4章分支与循环程序设计4.1.2SF──符号标志SF用于记载两个有符号数运算结果的符号位。执行加减法运算时,运算结果的最高位的值会被复制到SF中。【例4.2】判断例4.1中各指令执行后SF的值。【解】参照例4.1相应题目的计算结果有:(1)两数相加,和的第15位是0,故SF被置0。(2)两数相加,和的第7位是0,故SF被置0。(3)两数相加,和的第7位是1,故SF被置1。(4)两数相减,差的第15位是1,故SF被置1。(5)两数相减,差的第15位是0,故SF被置0。(6)两数相减,差的第7位是1,故SF被置1。第4章分支与循环程序设计如果把两个带符号数相减,根据SF的设定情况能否判定它们的大小关系呢?并非如此,比如例4.2中的第(6)小题,相减后SF为1表示差是负数,这应该说明“被减数比减数小”,但仔细观察两个操作数不难发现,以带符号数看待,被减数78H是正数,而减数9FH却是负数,当然是被减数大。出现这种现象的原因是相减的差已超出带符号数的表示范围。判断带符号数的大小关系还需要下面的OF标志位的配合。第4章分支与循环程序设计4.1.3OF──溢出标志如果CPU执行两个带符号数的加法或减法运算,结果超出了带符号数的表示范围,则把OF置1,这种现象称为带符号数加减运算溢出,没有超出范围则把OF清0。那么,是不是对OF的设置都需要经过准确计算,然后与带符号数表示范围进行比较才能确定呢?其实计算机并不做范围检验,而是按表4.1中列出的情况进行设置的。第4章分支与循环程序设计表4.1加减法运算对OF的设置方法加法减法第1加数符号位第2加数符号位和的符号位(SF)设置OF被减数符号位减数符号位差的符号位(SF)设置OF0000000000110010010001000110011110001001101010101101110011101110第4章分支与循环程序设计【例4.3】判断例4.1中各指令执行后OF的值。【解】参照表4.1,比较操作数及运算结果的正负号可知:(1)OF=0(2)OF=0(3)OF=1(4)OF=1(5)OF=0(6)OF=1第4章分支与循环程序设计4.1.4ZF──零标志ZF的设置比较简单,如果运算结果为0,则ZF被置1,结果不为0则ZF被置0。【例4.4】判断例4.1中各指令执行后ZF的值。【解】根据例4.1计算结果有,除第(5)小题使ZF置1外,其余题目都使ZF置0。加减法运算指令对4个标志位的设置都有具体规定,一条加法指令或一条减法指令在计算出结果的同时,还把4个标志位都根据运算情况设置了相应的值。编程者对各标志位应有所取舍,如果程序涉及的操作数是无符号数,应该根据CF和ZF的值做相应处理,如果操作数是带符号的,则应该看SF、OF和ZF。第4章分支与循环程序设计4.1.5MOV、ADD、SUB、MUL、DIV指令对标志位的影响(1)MOV指令不影响任何标志位,各标志位在MOV指令执行前是什么值,执行后仍然保持原值。(2)ADD指令和SUB指令对标志位的设置情况在前面已经说明。(3)MUL指令对ZF和SF无定义,这是指指令执行后对这两个标志位的值有影响,但它们的值没有明确的意义,这与无影响是不同的;对于CF和OF,如果乘积的高一半为0,即字节型乘法的结果AH=0或者字型乘法的结果DX=0,则CF和OF都被置0,否则两个标志位都被置1。这一设置规则可以用来检查字节相乘的积是字节还是字,或者检查字相乘的积是字还是双字。(4)DIV指令对4个条件标志位都无定义(注意,不是无影响)。第4章分支与循环程序设计【指令格式】CMPd1,d2【功能】用操作数d1减去操作数d2,把运算的情况反映到条件标志位上,运算得到的差并不送到任何一个操作数中,即CMP指令并不改变两个操作数的值。【说明】(1)CMP指令专门用于两个数据的比较,数据本身可以是无符号数,也可以是带符号数。(2)CMP指令关于操作数寻址方式的要求与SUB指令完全相同。(3)CMP指令对各标志位的设定规则也与SUB指令相同。4.1.6CMP指令第4章分支与循环程序设计【指令格式】JMP标号【功能】让计算机转到标号所在处继续执行。通常情况下,标号的定义与JMP指令应该在同一个段中,这种情况下的跳转称为段内跳转,只需要改变IP的值即可实现转移。标号定义的位置与JMP指令的位置之间没有先后限制,JMP指令既可以实现向前跳转,也可以用于向后跳转。程序中还可以多处使用JMP指令转到同一个标号。如果标号的定义与JMP指令不在同一个段中,跳转就需要同时修改CS和IP才能实现,这种跳转称为段间跳转。4.2跳转类指令4.2.1无条件跳转指令──JMP第4章分支与循环程序设计【例4.5】下面的程序段用来说明JMP指令的用法:……JMPlabMOVAX,BXADDAX,CXlab:MOVDX,AX……计算机本应该依照指令编写的次序逐条执行,但在执行到JMPlab这一行指令时,将修改IP的值,从而跳过下面的两行,直接转到lab所在的那一行去执行“MOVDX,AX”指令。第4章分支与循环程序设计4.2.2条件跳转指令4.2.2.1以单个标志位为条件的跳转指令1.JZ指令(JumpifZFSet)【指令格式】JZ标号【功能】如果ZF标志位的值是1,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。2.JNZ指令(JumpifZFNotSet)【指令格式】JNZ标号【功能】如果ZF标志位的值是0,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。第4章分支与循环程序设计3.JC指令(JumpifCFSet)【指令格式】JC标号【功能】如果CF标志位的值是1,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。4.JNC指令(JumpifCFNotSet)【指令格式】JNC标号【功能】如果CF标志位的值是0,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。5.JS指令(JumpifSFSet)【指令格式】JS标号【功能】如果SF标志位的值是1,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。第4章分支与循环程序设计6.JNS指令(JumpifSFNotSet)【指令格式】JNS标号【功能】如果SF标志位的值是0,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。7.JO指令(JumpifOFSet)【指令格式】JO标号【功能】如果OF标志位的值是1,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。8.JNO指令(JumpifOFNotSet)【指令格式】JNO标号【功能】如果OF标志位的值是0,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。第4章分支与循环程序设计4.2.2.2相等和不等比较的跳转1.JE指令──等于跳转(JumpifEqual)【指令格式】JE标号【功能】如果ZF为1,则转到标号处继续执行,否则按正常顺序执行下一条指令。比较两个数据是否相等,通常先用CMP指令把两个操作数相减,用计算结果设置标志位,然后用JE指令根据ZF的值决定是否跳转。若ZF为1表示相减结果为0,即两数相等,则转移。所以JE与JZ实质上是同一条指令,并且汇编程序翻译成机器码后的结果也是相同的,是同一机器指令的两种不同的汇编语言写法。第4章分支与循环程序设计2.JNE指令──不等于跳转(JumpifNotEqual)【指令格式】JNE标号【功能】如果ZF为0,则转到标号处继续执行,否则按正常顺序执行下一条指令。这是JNZ指令的另一种写法。第4章分支与循环程序设计4.2.2.3无符号数大小比较的跳转1.JA指令──无符号数大于跳转(JumpifAbove)【指令格式】JA标号【功能】如果ZF和CF都是0,则转到标号处继续执行,否则按正常顺序执行下一条指令。对于两个无符号数d1和d2,当“CMPd1,d2”指令设置了标志位后,如果ZF和CF都是0,表示两数相减的结果不为0,最高位也不需要向前借位,则可判定d1d2。与JA指令完全等同的写法是JNBE(JumpifNotBelownorEqual)。第4章分支与循环程序设计2.JNA指令──无符号数小于或等于跳转(JumpifNotAbove)【指令格式】JNA标号【功能】如果ZF为1,或者CF为1,则转到标号处继续执行,否则按正常顺序执行下一条指令。用“CMPd1,d2”指令设置标志位之后,ZF为1表示d1=d2,而CF为1表示把两个数作无符号数看待时,两数相减最高位向前有借位,所以可判定d1d2。这是两个条件的“或”关系,只要其中一个满足已可判定d1≤d2。与JNA指令完全等同的写法是JBE(JumpifBeloworEqual)。第4章分支与循环程序设计3.JB指令──无符号数小于跳转(JumpifBelow)【指令格式】JB标号【功能】如果CF为1,则转到标号处继续执行,否则按正常顺序执行下一条指令。这是根据两个无符号数是否满足“小于”关系决定是否跳转的指令。与JB指令完全等同的写法有JNAE(JumpifNotAbovenorEqual)和JC。4.JNB指令──无符号数大于或等于跳转(JumpifNotBelow)【指令格式】JNB标号【功能】如果CF为0,则转到标号处继续执行,否则按正常顺序执行下一条指令。这是根据两个无符号数是否满足“不小于”关系决定是否跳转的指令。与JNB指令完全等同的写法有JAE(JumpifAboveorEqual)和JNC。第4章分支与循环程序设计4.2