- 什么是转移指令:
段内转移:指令转移方式
IP=IP+位移
。等同于JMP 当前IP+需要位移字节段内短转移:
JMP SHORT 标号
段内短转移,位移为8bit位,最高位为符号位。剩余7个bit位可位移,位移间距是:
-128~127
,也就是说在编译之后,使用JMP SHORT 标号
指令往前转移最多128个字节,往后转移最多127个字节。代码示例:
ASSUME CS:CODE CODE SEGMENT START: MOV AX,0 MOV BX,0 JMP SHORT S ADD AX,1 ; 机器码:B80100 ADD AX,3 ; 机器码:B80300 DB 121 DUP(0) S: INC AX CODE ENDS END START
段内近转移:
JMP NEAR PTR 标号
段内近转移,位移为16个bit位,最高位为符号bit位,剩余15个bit为可进行位移,位移间距是
-32768~32767
,在编译之后,使用JMP NEAR PTR 标号
转移指令至多往前转移32768个字节,往后至多转移32767字节。代码示例:
ASSUME CS:CODE CODE SEGMENT START: MOV AX,0 MOV BX,0 JMP NEAR PTR S ADD AX,2 DB 128 DUP(0) S: INC AX CODE ENDS END START
为啥近转移比短转移多了个
PTR
关键字?这是网上搜索到的一句话:
汇编里面 ptr 是规定 的 字 (既保留字),是用来临时指定类型的
段间转移:
JMP FAR PTR 标号
使用内存单元进行指令转移
使用内存单元进行近转移:
JMP WORD PTR 内存单元地址
从内存单元地址处开始存放着一个字,是转移目的地指令的偏移地址。
偏移地址计算方式:JMP DS:[BX]。将BX指向的内存单元中的数据用于IP寄存器的值。跳转到指定的位置。偏移量范围参考:
段内近转移
使用内存单元进行段间转移:
JMP DWORD PTR 内存单元地址
有条件转移
JCXZ 指令
JCXZ 标号
为有条件转移指令之一,它用于判断CX是否等于0,如果等于0,则执行指令转移,否则它什么都不做,程序继续往下执行,用Java语言的语法表示为:if(cx == 0){jmp ip}。这样举例或许更好理解JCXZ指令的作用代码示例:
ASSUME CS:CODE,DS:DATA CODE SEGMENT START: MOV AX,DATA MOV DS,AX MOV AX,0 MOV BX,0 S: MOV CL,DS:[BX] ; 将内存单元中的值取出,保存到CL中 JCXZ SAVE ; 如果CX==0时,转移到SAVA标号处,保存当前BX的偏移量 INC BX ; 如果CX!=0时,BX+1,也就是偏移量+1。继续转移到S标号处执行 JMP SHORT S SAVE: MOV DX,BX MOV AH,4CH INT 21H CODE ENDS DATA SEGMENT DB 12,20,32,00,36 DATA ENDS END START
LOOP 指令
LOOP 标号
是一个循环指令,但是也是属于有条件转移指令的一种。需要注意的是所有循环指令都是短转移
。它判断CX中的值,是否需要进行指令转移。跟JCXZ
指令恰恰相反,LOOP指令用判断CX-1之后是否不等于0,如果不等于0则转移到标号处。如果等于0,则程序往下执行。用Java语言表示的话,应该是下面代码所执行的效果,其中while就相当于LOOP指令,每次指令LOOP指令转移时,先将CX中的值-1,然后在判断CX不等于0Assembly代码:
ASSUME CS:CODE CODE SEGMENT MOV CX,32 S: ; LOOP循环体代码段,这里只能有125个字节哦 LOOP S COED ENDS
Java代码:
public class Test{ public static void main(String[] args){ int cx = 32; while((--c) != 0){ // 标号处到LOOP指令之间的代码段 } } }
以上举的两个例子都是使用CX寄存器是否为0进行条件判断的。还有使用标志寄存器作为条件进行指令转移的指令,详情查看:《条件转移指令之使用标志寄存器进行指令转移》