「x86」- 转移指令(Control Transfer Instructions)

类别 指令 全称 功能
06 CALL    
06 INT    
06 JCXZ    
06 JMP Jump  
06 LOOP    
06 LOOPNE    
06 LOOPNZ    
06 LOOPZ    
06 RET    

JMP, jump

转移类型:相对短转移
指令格式:JMP SHORT <PTR>
转移范围:8-bit(-128~127)

转移类型:相对近转移
指令格式:JMP NEAR <PTR>
转移范围:16-bit(-32768~32767)

转移类型:间接绝对近转移
指令格式:JMP NEAR <REG>
转移范围:段内转移,使用在 <REG> 中值替换 IP 的当前指,以进行转移

转移类型:直接绝对远转移
指令格式:JMP <SEGMENT>:<OFFSET>
转移范围:使用 <SEGMENT> 替换 CS 的值,使用 <OFFSET> 替换 IP 的值,以进行转移;

转移类型:间接绝对远转移
指令格式:JMP FAR [ADDRESS]
转移范围:从 [ADDRESS] 中,获取转移地址,并修改 CS 与 IP 的值,以进行转移;

CALL, call procedure

指令的执行过程

1)将当前 IP 入栈,或 CS 和 IP 入栈
2)转移

根据位移进行转移

该转移为段内转移,只修改 IP 内容

指令格式:
call <lable>

执行过程:
1)(SP) = (SP – 2), ((SS) * 16 + (SP)) = (IP)
2)(IP) = (IP) + 16-bit offset

此 16-bit offset 为:
1)在编译时算出并写入指令中
2)范围为 -32768 – 32767,采用补码表示
3)16-bit offset = 标号地址 – 在 CALL 后的下条指令地址

转移地址 在指令中

该转移为段间转移,同时修改 CS IP 内容

指令格式:
call far ptr <label>

执行过程:
1)(SP) = (SP – 2), ((SS) * 16 + (SP)) = (CS)
2)(SP) = (SP – 2), ((SS) * 16 + (SP)) = (IP)
3)(CS) = 标号所在段的段地址
4)(IP) = 标号所在段的偏移地址

转移地址 在寄存器中

该转移为段内转移,只修改 IP 内容

指令格式:
call <register>

执行过程:
1)(SP) = (SP – 2), ((SS) * 16 + (SP)) = (IP)
2)(IP) = (<register>)

转移地址 在内存中

该转移为段间转移,同时修改 CS IP 内容

指令格式:
call word ptr <memory address>

执行过程:
1)(SP) = (SP – 2), ((SS) * 16 + (SP)) = (IP)
2)(IP) = (<memory address>)

指令格式:
call dword ptr <memory address>

执行过程:
1)(SP) = (SP – 2), ((SS) * 16 + (SP)) = (CS)
2)(SP) = (SP – 2), ((SS) * 16 + (SP)) = (IP)
3)(CS) = (<memory address> + 2)
4)(IP) = (<memory address>)

参考文献

Control Transfer Instructions – x86 Assembly Language Reference Manual