本篇主要介绍 8086CPU 的转移指令。
转移指令
修改 IP 或 同时修改 CS 和 IP 的指令称为转移指令。也就是说转移指令是能控制 CPU 执行内存中某处代码的指令。
8086CPU 转移行为分类:
只修改 IP ,称为段内转移,例如:jmp ax
根据转移指令对 IP 修改范围,段内转移又可以分为:
- 短转移:修改范围为 -128 ~ 127,2^7 = 128
- 近转移:修改范围为 -32768 ~ 32767,2^15 = 32768
- 短转移:修改范围为 -128 ~ 127,2^7 = 128
- 同时修改 CS 和 IP ,称为段间转移,例如:jmp 1000:0
依据位移进行转移的 jmp 指令
jmp short 标号(转到标号处执行指令)
- 8 位位移 = “标号”处的地址 - jmp 指令后的第一个字节的地址
- short 指明此处的位移为 8 位位移
- 8 位位移的范围为 -128 ~ 127 ,用补码表示
- 8 位位移由编译程序在编译时算出
jmp near ptr 标号 16 位位移
例如下面的程序:
assume cs:codesg |
当程序执行完后 ax 中的内容为 1 ,因为执行 jmp short s 后跳过了 add ax,1。从 debug (下图所示)中可以清楚的看到 jmp short s 直接由编译器编译成了 jmp 0008。来验证一下上面的计算方法 “8 位位移 = “标号”处的地址 - jmp 指令后的第一个字节的地址”,标号处的偏移地址为 8(3+2+3) ,jmp 指令后的第一个字节的地址为 5(3+2),即 8 位位移为 3,也就是下图中 jmp 处对应的机器码 EB03 中的 03。

我们在上面的 jmp 指令前后各加一条指令再来验证下,代码如下:
assume cs:codesg |
标号处的偏移地址为 14,jmp 指令后的第一个字节的地址为 8,则 8 位位移为 6。如下图所示。

“jmp near ptr 标号” 和 “jmp short 标号” 的功能相近,实现的段内近转移,它的功能为:
- 16 位位移 = “标号”处的地址 - jmp 指令后的第一个字节的地址
- near ptr 指明此处的位移为 16 位位移
- 16 位位移的范围为 -32768 ~ 32767 ,用补码表示
- 16 位位移由编译程序在编译时算出
转移的目的地址在指令中的 jmp 指令
“jmp far ptr 标号” 实现的是段间转移,也称为远转移,功能如下:
- (CS)= 标号处所在段的段地址
- (IP)= 标号在段中的偏移地址
far ptr 表明了指令用标号段的段地址和偏移地址来同时修改 CS 和 IP。代码如下所示:
assume cs:codesg |
在 debug 中能够清楚的看到 jmp far ptr s 要跳转的段地址和偏移地址

转移地址在内存中的 jmp 指令
转移地址在内存中的 jmp 指令有两种方式:
- jmp word ptr 内存单元地址(段内转移)
- jmp dword ptr 内存单元地址(段间转移)
“jmp word ptr 内存单元地址” 的功能是从内存单元地址开始处存放着一个字,是转移的偏移地址。
“jmp dword ptr 内存单元地址” 的功能是从内存单元地址开始处存放着两个字节,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。
jcxz 指令
jcxz 是条件转移指令,指令格式为:jcxz 标号(如果 cx 的值为 0,跳到标号处执行),所有的条件转移指令都是短转移。
loop 指令
loop 指令为循环指令,指令格式为:loop 标号 (如果 cx 的值为不为 0 ,跳到标号处执行),所有的循环指令都是短转移。