第4章 指令系统(二) - 图文

格式: 1)SCAS DST; 2)SCASB(字节); 3)SCASW(字) 执行的操作: 字节操作:((AL))-(DI),(DI)←(DI)±1 字操作: ((AX))-(DI),(DI)←(DI)±2 指令把AL(或AX)的内容与由(DI)指定的在附加段中的一个字节(或字)进行比较,并不保存结果,只根据结果置条件码。指令的其他特性和MOVS的规定相同。 4.3.5 控制转移指令 一般情况下指令是顺序地逐条执行的,但实际上程序不可能全部顺序执行而经常需要改变程序的执行流程,控制转移指令分成无条件转移指令和条件转移指令两大类。 1.无条件转移指令 无条件地转移到指令指定的地址去执行从该地址开始的指令。转移可以分成两类:段内转移和段间转移。段内转移是指在同一段的范围之内进行转移,此时只需改变IP寄存器的内容,即用新的转移目标地址代替原有的IP的值就可达到转移的目的。段间转移则是要转到另一个段去执行程序,此时不仅要修改IP寄存器的内容,还需要修改CS寄存器的内容才能达到目的,因此,此时的转移目标地址应由新的段地址和偏移地址两部分组成。 1) 直接短转移: 格式:JMP SHORT OPR 执行的操作:(IP)<--(IP)+8位位移量 其中8位位移量是由目标地址OPR 确定的。转移的目标地址在汇编格式中可直接使用符号地址,而在机器执行时则是当前的IP 值(即JMP指令的下一条指令的地址)与指令中指定的8位转移格式只允许在-128到+127字节的范围内转移。 2) 段内直接近转移: 格式:JMP NEAR RTP OPR 执行的操作:(IP)<-- (IP)+16位位移量 可以看出除位移量位16位外,它和段内短转移一样,也采用相对寻址方式,在汇编格式中OPR也只需要使用符号地址。由于位移量位16位,它可以转移到段内的任一个位置。 3) 段内间接转移: 格式:JMP WORD PRT OPR 执行的操作:(IP)<- (EA) 由于有效地址EA值由OPR的寻址方式确定。它可以使用除立即数方式以外的任一种寻址方式,如果指定的是16位寄存器的内容送到IP寄存器中;如果指定的是存储器中的一个字,则把该存储单元的内容送到IP寄存器中去。在4.1.3节中我们已经说明,这里不再细述。 4) 段间直接(远)转移: 格式:JMP WORD PTR OPR 执行的操作:(IP)<- OPR 的段内偏移地址 (CS)<- OPR 所在段的段地址 在这里使用的是直接寻址方式。在汇编格式中OPR可使用符号地址,而机器语言中则要指定转向地址的偏移地址和段地址。 5) 段间间接转移: 格式: JMP DWORD PTR OPR 执行的操作:(IP)<- (EA) (CS)<-- EA+2)

13

其中EA由OPR的寻址方式确定,它可以使用除立即数及寄存器方式以外的任何存储器寻址方式,根据寻扯方式求出EA后,把指定存储单元的第一个字的内容送到IP寄存器,并把下一个字的内容送到CS寄存器,这样就实现了段间跳转。 最后说明一下,JMP指令不影响条件码。 2.条件转移指令 条件转移指令根据上一条指令所设置的条件码来判别测试条件,每一种条件转移有它的测试条件,满足测试条件则转移到由指令指出的转向地址去执行那里的程序;如不满足条件则顺序执行下一条指令。因此,当满足条件时:(IP)<-- (IP)+符号扩展到16位后的位移量D8,如不满足测试条件则(IP)不变。可见条件转移指令使用了相对寻址方式,在汇编格式中OPR应指定一个目标地址,这个目标地址应在本条转移指令下一条指令地址的-128到+127个字节的范围之内。另外,所有的条件转移指令都不影响条件码。下面我们把条件转移指令分为四组来讨论。 1)根据单个条件樗的设置情况转移。这组包括10种指令。它们一般适用于测试某一次运算的结果并根据其不同特征产生程序分支作不同处理的情况。 ① JZ(或JE)(Jump if zero,or equal)结果为零(或相等)则转移。 格式:JZ(或JE) OPR 测试条件:ZF=1 ② JNZ(或JNE)(Jump if zero,or equal)结不为零(或不相等)则转移。 格式:JNZ(或JNE) OPR 测试条件:ZF=0 ③ JS(Jump if sign)结果为负则转移 格式:JS OPR 测试条件:SF=1 ④ JNS(Jump if not sign)结果为正则转移 格式:JNS OPR 测试条件:SF=0 ⑤ JO (Jump if overflow)溢出则转移 格式:JO OPR 测试条件:OF=1 ⑥ JNO(Jump if not overflow)不溢出则转移 格式:JNO OPR 测试条件:OF=0 ⑦ JP(或JPE)(Jump if parity, or parity even)奇偶位为1则转移。 格式:JP(或JPE) OPR 测试条件:PF=1 ⑧ JNP(或JPO)(Jump if not parity, or parity odd)奇偶位为0则转移 格式:JNP(或JPO) OPR 测试条件:PF=0 ⑨ JB(或JNAE,JC)(Jump if below,or not above or equal,or carry)低于,或者不高于或等于,或进位为1则转移。 格式:JB(或JNAE,或JC) OPR 测试条件:CF=1 ⑩ JNB(或JAE,或JNC)(Jump if not below,or above or equal ,or ont carry)不低于,或者高于或等于,或进位为零则转移

14

格式:JNB(或JAE,或JNC) OPR 测试条件:CF=0 例4.3.16: 比较两个数是否相等,如相等做动作1,否则做动作2.可编写程序为: ? CMP AX,BX JE ACTION_2 ? }ACTION_1 ACTION_2: ? }ACTION_2 或者: ? CMP AX,BX JNZ ACTION_2 ? }ACTION_1 ACTION_1 ? }ACTION_2 2) 比较两个无符号数,并根据比较的结果转移。 ① JB(或JNAE,JC)低于,或者不高于或等于,或进位为1则转移。 ② JNB(或JAE,或JNC)不低于,或者高于或等于,或进位为零则转移 以上两种指令与上一组指令中的最后两种完全相同。 ③ JBE(或JNA,(Jump if below or equal,or not above )低于或等于,或不高于则转移。 格式:JBE(或JNA) OPR 测试条件:CF V ZF=0 3) 比较两个带符号数,并根据比较结果转移。 ① JL或(JNGE)(Jump if not less ,or not greater or equal )小于,或者不大于或者等于则转移。 格式: JL(或JNGE) OPR 测试条件:CF V ZF=0 ② JNL或(JGE)(Jump if not less ,or greater or equal)不小于,或者不大于或者等于则转移。 格式:JNL(或JGE) OPR 测试条件:CF V ZF=0 ③ JLE或(JNG)(Jump if not less ,or not greater)小于或等于,或者不大于则转移。 格式:JLE(或JNG) OPR 测试条件:(SF OF) V ZF=1 ④ JNLE或(JG)(Jump if not less or equal,or greater)不小于或等于,或者大于则转移。 格式: JNLE(或JG) OPR 测试条件:(SF OF) V ZF=0 4) 测试CX的值为0则转移指令 JCXZ(Jump if CX register is zero) CX寄存器的内容为零则转移。

15

格式:JCXZ OPR 测试条件:(CX)=0 CX寄存器经常用来设置计数值,所以这条指令可以根据CX寄存器内容的修改情况来产生两个不同程序分支。 3.循环指令 (1) LOOP(LOOP)循环指令 格式:LOOP OPR 测试条件:(CX)≠0 (2) LOOPZ/LOOPE(Loop while zero,or equal)当为零或相等时循环指令 格式:LOOPZ(或LOOPE) OPR 测试条件:ZF=1且(CX)≠0 (3) LOOPNZ/LOOPNE(loop while nonzero,or not equal)当不为零或不相等时循环指令 格式:LOOPNZ(或LOOPNE) OPR 测试条件:ZF=0且(CX)≠0 这三条指令的执行步骤是: 1) (CX)〈--(CX) - 1 2) 检查是否满足测试条件,如满足则(IP)〈--(IP)+D8的符号扩展。 可见这里使用的是相对方式,在汇编格式中OPR必须指定一个表示转向地址的标号(符号地址),而在机器指令里则用8位位移量D8来表示转向地址与当前IP值的差。由于位移量只有8位,所以转向地址必须在该循环指令的下一条指令地址的-128~+127字节的范围之内。当满足测试条件就转向地址去执行,即实行循环,如不满足测试条件则IP值不变,即退出循环,程序继续顺序执行。 循环指令不影响条件码。 除LOOP指令外另外两条LOOPZ和LOOPNZ指令提供了提前结束循环的可能性。有时需要在字符串中查找一个字符,在找到后就可提前结束循环而不需要一直查找到底了。此时就LOOPZ或LOOPNZ来处理。 4.子程序 子程序结构相当于高级语言中的过程。便于模块化程序设计,往往把程序中某些具有独立功能的部分编写成独立的程序模块,称之为子程序.程序中可由调用程序(或称主程序)调用这些子程序,而在子程序执行后又返回调用程序继续执行。为实现这一功能,IBM-PC机提供了以下指令: (1) CALL(call)调用指令 1) 段内直接调用 格式:CALL DST 执行的操作:1) (SP)〈-- (SP)-2; ((SP)+1,(SP))〈-- (IP) 2) (IP)〈-- (IP)+D16 可以看出,这条指令的第一步操作是把子程序的返回地址(即调用程序CALL指令的下一条指令的地址)存入堆栈中,以便子程序返回主程序时使用。第二步操作则是转移到子程序的入口地址继续执行。指令中DST给出转向地址(即子程序的入口地址,也就是子程序的第一条指令的地址),D16即为机器指令中的位移量,它是转向地址和返回地址之间的差值。 2) 段内间接调用 格式:CALL DST 执行的操作:1) (SP)〈-- (SP)-2; ((SP)+1,(SP))〈-- (IP) 2) (IP)〈-- (EA)

16

联系客服:779662525#qq.com(#替换为@)