控制转移指令通过改变CS:IP来控制程序的执行流程。这类指令包括无条件转移指令、条件转移指令、循环指令、子程序调用和返回指令以及中断和中断返回指令。
⑴ 无条件转移
JMP 跳转
⑵ 条件转移
JZ/JNZ 结果为零/不为零则转移
JS/JNS 结果为负/为正则转移
JO/JNO 溢出/不溢出则转移
JP/JNP 奇偶位为1/为0则转移
JB/JNB 低于/不低于则转移
JBE/JNBE 低于等于/高于则转移
JL/JNL 小于/不小于则转移
JLE/JNLE 小于等于/大于则转移
JCXZ CX为零则转移
⑶ 循环指令
LOOP 循环
LOOPZ/LOOPE 为零/相等时循环
LOOPNZ/LOOPNE 不为零/不等时循环
⑷ 子程序调用与返回
CALL 调用
RET 返回
⑸ 中断及中断返回
INT 中断
INTO 溢出则中断
IRET 中断返回
程序中指令的执行顺序是由CS:IP来决定的,程序转移类指令可改变IP或CS、IP的内容,从而控制指令的执行顺序,实现指令转移、程序调用等功能。
1 无条件转移指令
JMP指令控制程序无条件地跳转到目的单元,使用JMP指令可有三种格式:
⑴ JMP SHORT label 短转移(short jump)
⑵ JMP NEAR PTR label 近转移(near jump)
● JMP label 直接转移(direct jump)
● JMP reg 寄存器间接转移(register indirect jump)
● JMP WORD PTR OPR 存储器间接转移(memory indirect jump)
⑶ JMP FAR PTR label 远转移(far jump)
短转移的目标地址(或称转向地址)相对于当前IP值的位移量在-128至+127字节之间,当前IP值是指JMP指令的下一条指令的地址(如图3.11所示)。对短转移JMP,机器指令的第一个字节为操作码EB,第二个字节为位移量00~FF,这是一个带符号的补码数。转向地址的计算方法为:(IP)当前+8位位移量。操作符SHORT指示汇编程序将JMP指令汇编成一个2字节指令。
⑴ JMP SHORT label 短转移(short jump)
执行操作:(IP) ← (IP)当前+8位位移量
短转移示意图
⑵ JMP NEAR PTR label 近转移(near jump)
近转移是JMP指令的缺省格式,可以写为"JMP label"。它可在当前代码段内转移,机器指令的操作码是E9,位移量是16位的带符号补码数。指令中的转向地址可以是直接寻址方式、寄存器寻址方式、寄存器间接方式和存储器寻址方式。
● JMP label 直接转移(direct jump)
执行操作:(IP) ← OFFSET label = (IP)当前+16位位移量
转移的目标地址在指令中可直接使用符号地址,由于位移量为16位,它的转移范围应是-32768至+32767,也就是说,近转移指令可以转移到段内的任一个位置。
● JMP reg 寄存器间接转移(register indirect jump)
执行操作:(IP) ← (reg)
转移的目标地址在寄存器中,例如指令"JMP BX"执行的结果,将BX的内容送给IP。
● JMP WORD PTR OPR 存储器间接转移(memory indirect jump)
执行操作:(IP) ← (PA+1,PA)
存储器的物理地址PA由指令中的寻址方式确定,JMP指令执行的结果,把PA单元的字内容送到IP寄存器中。例如"JMP WORD PTR [DI]",物理地址PA = (DS)×24+(DI),指令执行的结果是(IP)= (PA+1,PA)。
⑶ JMP FAR PTR label 远转移(far jump)
执行操作:(IP) ← label的段内偏移地址
(CS) ← label所在段的段地址
远转移实现的是段间的跳转,即从当前代码段跳转到另一个代码段中,这意味着指令执行后,不仅要改变IP的值,CS也会得到一个新的段地址。在汇编指令中,远转移的目标地址也可以使用除立即寻址方式外的任何寻址方式来表示。
2 条件转移指令(conditional jump)
条件转移指令是在满足了规定的条件后才控制程序转移的一类指令,8086的条件转移指令总结在表3.4中。
所有条件转移指令都是短转移指令,转移的目标地址必须在当前IP地址的-128至+127字节范围之内,因此条件转移指令是2字节指令。
计算转向地址的方法和无条件短转移指令是一样的,看例3.40的反汇编代码。
例3.40程序中的"JNZ AGAIN"汇编成"JNZ 000D",000D是标号AGAIN的地址,指令"JNZ 000D"的机器代码是75FA,75是操作码,FA是位移量。当CPU读取JNZ指令后,IP寄存器自动加2(JNZ的指令长度)指向了下一条指令(MOV),此时IP的当前值是0013。计算转向地址时,(IP)当前+位移量 = 0013+FA = 0013+FFFA = 000D,这正是AGAIN的偏移地址。实际上FA是-6的补码,8位的FA与16位的0013相加时,FA符号扩展成为FFFA,相加的加结果为000D。
表3.4 条件转移指令 分类 指 令 转 移 条 件 说 明
(Ⅰ) JZ/JE ZF=1 为零/相等, 则转移
JNZ/JNE ZF=0 不为零/不相等, 则转移
JS SF=1 为负, 则转移
JNS SF=0 为正, 则转移
JO OF=1 溢出, 则转移
JNO OF=0 不溢出, 则转移
JP PF=1 奇偶位为1, 则转移
JNP PF=0 奇偶位为0, 则转移
JC CF=1 进位位为1, 则转移
JNC CF=0 进位位为0, 则转移
(Ⅱ) JB/JNAE/JC CF=1 低于/不高于等于, 则转移
JNB/JAE/JNC CF=0 不低于/高于等于, 则转移
JBE/JNA (CF ZF)=1 低于等于/不高于, 则转移
JNBE/JA (CF ZF)=0 不低于等于/高于, 则转移
(Ⅲ) JL/JNGE (SF OF)=1 小于/不大于等于, 则转移
JNL/JGE (SF OF)=0 不小于/大于等于, 则转移
JLE/JNG ((SF OF) ZF)=1 小于等于/不大于, 则转移
JNLE/JG ((SF OF) ZF)=0 不小于等于/大于, 则转移
(Ⅳ) JCXZ (CX)=0 CX的内容为0, 则转移
注: (Ⅰ)根据条件码的值转移 (Ⅱ)比较两个无符号数,根据比较的结果转移
(Ⅲ)比较两个带符号数,根据比较的结果转移 (Ⅳ)根据CX寄存器的值转移
例
1050:0000 B86610 MOV AX,1040
1050:0003 8ED8 MOV DS,AX
1050:0005 B90500 MOV CX,0005
1050:0008 BB0000 MOV BX,0000
1050:000D 0207 AGAIN: ADD AL,[BX]
1050:000F 43 INC BX
1050:0010 49 DEC CX
1050:0011 75FA JNZ 000D
1050:0013 A20500 MOV [0005],AL
1050:0016 B44C MOV AH,4C
1050:0018 CD21 INT 21
例 假设程序进行两个带符号数的比较,并根据比较结果转移,其中(AL)=80H,(BL)=01,请指出下面 两组指令的转向地址。
⑴ CMP AL,BL ⑵ CMP AL,BL
JL XY JB XY
答:⑴ 转向目标地址XY;⑵不能实现转移。
执行CMP指令时,(AL)-(BL)=80-01=7F,条件码设置为:SF=0,OF=1,CF=0。执行JL指令时,测试转移条件:SFOF = 0 1 =1,说明满足(AL)<(BL)的转移条件,因此,(IP)←XY的偏移地址,程序即转移到XY单元执行新的指令。
JB指令的转移条件为CF=1,而CMP的执行结果使CF=0,所以不能引起转移。