首页 理论教育 控制转移指令

控制转移指令

时间:2023-02-28 理论教育 版权反馈
【摘要】:前几节介绍的指令都不能改变程序顺序执行的特点。程序控制指令包括转移指令、循环指令、子程序调用及返回指令、中断调用及返回指令。可实现段内转移。这类指令本身并不影响标志。检测单个标志位实现转移的条件转移指令。这组指令根据一个标志位的设置情况决定是否转移,表2-10给出了指令的汇编格式、功能和测试条件。根据两个无符号数的比较结果实现转移的条件转移指令。

2.3.5 控制转移指令

程序控制指令可以控制程序的流向,可以实现转移、循环、调用、返回等功能。前几节介绍的指令都不能改变程序顺序执行的特点。程序控制指令包括转移指令、循环指令、子程序调用及返回指令、中断调用及返回指令。

1.无条件转移指令JMP

格式:JMP DST

功能:无条件转移到DST所指向的地址。

说明:DST为转移的目标地址(或称转向地址),转移地址分为段内和段间转移。段内转移指令只改变IP值,不改变CS值,所以只能实现同段内的转移。而段间转移除了改变IP值,还要改变CS值,所以可以实现段间转移。

(1)段内直接短转移。

格式:JMP SHORT LABEL

功能:无条件转移到标号(LABEL,目标地址)处。

说明:标号与JMP指令在同段内,使用段内直接短转移寻址方式。指令长度短,可用于实现短距离的段内转移。

【例2-55】

JMP SHORT ABC;无条件转移到ABC标号处

ADD AX,BX

ABC:SUB AX,CX

(2)段内直接转移。

格式:JMP LABEL

或 JMP NEARPTRLABEL

功能:无条件转移到标号处。

说明:标号与JMP指令在同段内,使用段内直接寻址方式。在操作数长度为16位的情况下,可以实现距离当前IP值的±32K B范围内的转移。

【例2-56】

JMP ABC1;无条件转移到ABC1标号处

ADD AX,CX

…;距离超出+127字节,但仍在本段内

ABC1:SUB AX,CX

(3)段内间接转移。

格式:JMP REG/MEM

功能:无条件转移,其转向地址在通用寄存器或内存单元中。

说明:使用段内间接寻址方式。由于寄存器或内存单元中存放段内偏移量,所以必须是16位长。可实现段内转移。

【例2-57】 对于例2-56,可以把ABC1的偏移量送给通用寄存器,通过寄存器实现段内间接转移,程序段如下所示:

LEA BX,ABC1

JMP BX;转向地址ABC1在BX中

ADD AX,CX

ABC1:SUB AX,CX

【例2-58】 对于例2-57,可以把ABC1的偏移量送给内存单元,通过内存单元实现段内间接转移,程序段如下所示:

VARDW ?;为存放标号ABC1的偏移量预留一个字类型内存变量

MOV VAR,OFFSET ABC1;把ABC1的偏移量送给变量VAR

JMP WORD PTRVAR;转向地址在VAR变量中

ADD AX,CX

…;距离超出+127字节,但仍在本段内

ABC1:SUB AX,CX

(4)段间直接转移。

格式:JMP FARPTRLABEL

功能:无条件转移到标号(LABEL)处。

说明:标号与JMP指令分别处在不同段中,使用段间直接寻址方式。

【例2-59】

CODE1 SEGMENT

JMP FARPTRABC2;无条件转移到CODE2段中的ABC2标号处

CODE1 ENDS

CODE2 SEGMENT

ABC2:SUB AX,BX

CODE2 ENDS

(5)段间间接转移。

格式:JMP DWORD PTRMEM

功能:实现无条件段间间接转移。

说明:使用段间间接寻址方式。

【例2-60】 对于例2-59,若把ABC2的双字长地址指针放在变量VAR2中,即可通过VAR2实现段间间接转移,程序段如下所示:

VAR2 DD ABC2;初始化ABC2的偏移量在VAR2中,段基址在VAR2+2中CODE1 SEGMENT

JMP DWORD PTRVAR2

;通过VAR2无条件转移到CODE2段的ABC2标号处

CODE1 ENDS

CODE2 SEGMENT

ABC2:SUB AX,CX

CODE2 ENDS

当然,变量VAR2的地址也可以通过寄存器间接寻址方式、基址变址寻址方式等存储器操作数寻址方式得到。

2.条件转移指令

8086/8088系统提供了多个条件转移指令,执行这类指令时通过检测由前边指令已设置的标志位确定是否转移,所以它们通常跟在影响标志的算术和逻辑运算指令之后。这类指令本身并不影响标志。

条件转移指令的通用汇编格式:Jx LABEL

功能:如果条件为真,则转向标号(LABEL)处,否则顺序执行下一条指令。

说明:其中x为条件,LABEL是要转向的标号。在8086/8088系统中,该地址应在与当前IP值的-128~+127范围内,即只能使用与转移地址有关的寻址方式的段内短转移格式,其位移量占用一个字节。

下面分组讨论条件转移指令。

(1)检测单个标志位实现转移的条件转移指令。这组指令根据一个标志位的设置情况决定是否转移,表2-10给出了指令的汇编格式、功能和测试条件。

表2-10 检测单个条件标志位转移指令

img58

注:当能实现同一功能但指令助记符有两种形式时,在程序中究竟选用哪一种,这视习惯或用途而定。例如,对于指令JZ/JE LABEL,当比较两数相等转移时常使用JE,当比较某数为0转移时常使用JZ。

【例2-61】 比较AX和BX寄存器中的内容,若相等执行LP1,不等执行LP2。

方法1方法2

CMP AX,BX CMP AX,BX

JE LP1JNE LP2

LP2:…LP1:…

LP1:…LP2:…

(2)根据以实现两个带符号数的比较转移、两个带符号数的比较结果实现转移的条件转移指令。利用表2-11中提供的指令,可以实现两个有符号数的比较转移。

表2-11 根据两个带符号数的比较结果实现转移的条件转移指令

img59

注:G=G reater,L=Less,E=Eq ual,N=Not。

显然,表2-10中的指令JZ/JE LABEL和JNZ/JNE LABEL同样可以用于两个带符号数的比较转移。当能实现同一功能但指令助记符有两种形式时,在程序中究竟选用哪一种,这视习惯或用途而定。

(3)根据两个无符号数的比较结果实现转移的条件转移指令。利用表2-12中提供的指令,可以实现两个无符号数的比较转移。

表2-12 根据两个无符号数的比较结果实现转移的条件转移指令

img60

注:A=Above,B=Below,C=Carry,E=Eq ual,N=Not。可以看出,这里的高于相当于带符号数的大于,低于相当于带符号数的小于。

显然,表2-10中的指令JZ/JE LABEL和JNZ/JNE LABEL同样可以用于两个无符号数的比较转移。当能实现同一功能但指令助记符有两种形式时,在程序中究竟选用哪一种,这视习惯或用途而定。

【例2-62】 比较两个无符号数(在AX和BX中),把较大的数存放到AX中,把较小的数存放在BX中。

CMP AX,BX

JAE LP

XCHG AX,BX

LP:…

如果要比较两个数是有符号数,则程序段可改为:

CMP AX,BX

JG E LP

XCHG AX,BX

LP:…

同是一组数据,解释为带符号数和无符号数,其比较转移所选用的指令是不同的。对于无符号数,各部分均使用无符号数比较转移指令,对于带符号数,应使用有符号数比较转移指令。

3.测试CX值为0转移指令

这类指令不同于以上介绍的条件转移指令,因为它们测试的是CX寄存器的内容是否为0,而不是测试标志位。这类指令只能使用与转移地址有关的寻址方式的段内短转移格式,即位移量只能是8位的。

格式:JCXZ LABEL

功能:测试CX寄存器的内容,当CX=0时则转移,否则顺序执行。

注意:此指令经常用于在循环程序中判断循环计数的情况。

4.循环指令

循环指令可以控制程序的循环。对于Intel 80x86系列,所有循环指令的循环入口地址都只能在当前IP值的-128~+127范围内,即位移量只能是8位的,所以它们只能使用段内短转移格式。所有循环指令都用CX作为循环次数计数器,它们都不影响标志。

(1)循环指令LOOP。

格式:LOOP LABEL

功能:(CX)-1→CX,若(CX)≠0,则转向标号处执行循环体,否则顺序执行下一条指令。

注意:当初始化CX为0时,使用LOOP指令要循环64K次而不是0次。

(2)相等循环指令LOOPE/LOOPZ。

格式:LOOPE/LOOPZ LABEL

功能:(CX)-1→CX,若(CX)≠0and ZF=1,则转向标号处执行循环体,否则顺序执行下一条指令。

该指令常用于比较两个字符串是否相等的情况,前边的字符相等才有必要继续比较,否则终止比较。

(3)不等循环指令LOOPNE/LOOPNZ。

格式:LOOPNE/LOOPNZ LABEL

功能:(CX)-1→CX,若(CX)≠0and ZF=0,则转向标号处执行循环体,否则顺序执行下一条指令。

在LOOPNE或LOOPNZ指令前,应先把循环计数的初始值送给CX。该指令对在数据块中查找信息很有用,当未找到指定字符时继续查找,找到时退出。

5.子程序调用与返回指令

以下介绍8086/8088系统的子程序调用与返回指令,它完全适用于80386及以上CPU的实模式环境。子程序调用指令的详细介绍和使用,请参考第4章的内容。

(1)子程序调用指令CALL。

格式:CALLDST

功能:调用子程序。执行时先把返回地址压入堆栈,再形成子程序入口地址,最后把控制权交给子程序。

注意:其中DST为子程序名或子程序入口地址,其目标地址的形成与JMP指令类似,可以有段内直接/间接调用、段间直接/间接调用之分,只是不能使用段内直接寻址方式的SHORT格式。CALL指令的执行结果也是无条件转到标号处,但它与JMP指令的不同之处在于:前者转移后要返回,所以要保存返回地址;而后者转移后不再返回,所以不必保存返回地址。段内子程序调用指令实现同一段内的子程序调用,它只改变IP值,不改变CS值。段间子程序调用指令可以实现段间调用,执行时既改变IP值,也改变CS值。

①段内直接调用。

格式:CALLPRO1

或 CALLNEARPTRPRO1

功能:调用PRO1子程序。执行时先把当前IP值(返回地址)压入堆栈,再使IP=(IP)+DISP16,最后把控制权交给子程序。

说明:这种指令使用段内直接寻址方式。

【例2-63】 设子程序PRO1与CALL指令在同一段内,则调用PRO1子程序的指令是:

CALLPRO1

或 CALLNEARPRO1

②段内间接调用。

格式:CALLREG/MEM

功能:调用子程序。执行时先把当前IP值(返回地址)压入堆栈,再把指令指定的16位通用寄存器或内存单元的内容送给IP,最后把控制权交给子程序。

说明:这种指令使用段内间接寻址方式,指令指定的通用寄存器或内存单元中存放段内偏移量。

【例2-64】 可以把子程序入口地址的偏移量送给通用寄存器或内存单元,通过它们实现段内间接调用。

CALLBX;子程序入口地址的偏移量在BX寄存器中

CALLWORD PTR[BX];子程序入口地址的偏移量在数据段的BX所指向;的内存单元中

CALLWORD PTR[BX][SI];子程序入口地址的偏移量在数据段的BX+SI所;指向的内存单元中

③段间直接调用。

格式:CALLFARPTRPRO1

功能:调用PRO1子程序。执行时先把返回地址(当前IP值和当前CS值)压入堆栈,再把指令中的偏移量部分送给IP,段基址部分送给CS,最后把控制权交给子程序。

说明:这种指令使用段间直接寻址方式。

【例2-65】 设子程序PRO1与CALL指令不在同一段内,则段间直接调用PRO1子程序的指令是:

CALLFARPTRPRO1

④段间间接调用。

格式:CALLMEM

功能:调用子程序。执行时先把返回地址(当前IP值和当前CS值)压入堆栈,再把MEM的低字送给IP,高字送给CS,最后把控制权交给子程序。

说明:这种指令使用段间间接寻址方式,其中MEM为内存的双字长地址指针,低字部分为16位的偏移量,高字部分为段基址。

【例2-66】 对于例2-65,若子程序PRO1的入口地址(偏移量和段基址)放在变量VAR中,即可通过VAR实现段间间接调用,指令如下所示:

CALLDWORD PTRV AR;从V AR变量中得到子程序PRO1的入口地址实现

;调用

当然,变量VAR的地址也可以通过寄存器间接寻址方式、基址变址寻址方式等存储器操作数寻址方式得到。

【例2-67】 CALLDWORD PTR8[BX][SI]

(2)子程序返回指令RET。

执行这组指令可以返回到被调用处。有两条返回指令,它们都不影响标志。

格式:RET

功能:按照CALL指令入栈的逆序,从栈顶弹出返回地址(弹出一个字到IP,若子程序是FAR型还需再弹出一个字到CS),然后返回到主程序继续执行。

注意:无论子程序是NEAR型还是FAR型,返回指令的汇编格式总是用RET表示。但经汇编后会产生不同的机器码。在DEBUG中,段间返回指令被反汇编成RETF。

6.中断调用指令与中断返回指令

中断就是使计算机暂时挂起正在执行的进程而转去处理某种事件,处理完后再恢复执行原进程的过程。对某事件的处理实际上就是去执行一段例行程序,该程序被称为中断处理例行程序或中断处理子程序,简称为中断子程序。实模式下的中断处理方式和8086处理器相同。在8086/8088系统中,中断分为内中断(或称软中断)和外中断(或称硬中断),本节只介绍内中断的中断调用指令,其他内容在第5章中详细介绍。

(1)中断调用指令INT。

中断调用指令是程序员根据需要在程序的适当位置安排的,完全受程序控制,不像外中断那样随机产生。

格式:INT n;n为中断类型号。

功能:中断当前正在执行的程序,把当前的FLAG S、CS、IP值依次压入堆栈(保护断点),并从中断向量表的4n处取n类中断向量中断处理子程序入口地址,其中(4n)→IP,(4n+2)→CS,转去执行中断处理子程序。

【例2-68】 INT 21H

21H为系统功能调用中断,执行时把当前的FLAG S、CS、IP值依次压入堆栈,并从中断向量表的84H处取出21H类中断向量,其中(84H)→IP,(86H)→CS,转去执行中断处理子程序。

【例2-69】 INT 03H;断点中断

(2)中断返回指令IRET。

当从中断处理子程序返回时要使用中断返回指令,中断返回指令应放在中断处理子程序的末尾。

格式:IRET

功能:从栈顶弹出3个字分别送入IP、CS、FLAG S寄存器(按中断调用时的逆序恢复断点),控制返回到原断点继续执行。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈