汇编中的jmp转移指令:jmp short、jmp near ptr、jmp far ptr

从8086CPU的定义上来讲,只要是可以修改IP(指令指针寄存器),或同时修改CS(代码段寄存器)和IP(指令指针寄存器)的指令统称为转移指令。也就是说,转移指令是用来控制CPU指向内存中某处代码的指令。
那么通过转移区间的不同进行分类则有以下情况:
段内转移:只修改IP的值。也就是说,CS的值不变化。
段间转移:同时修改CS和IP的值。
如果再将上述情况通过修改范围再进行细分,那么段内转移又可分为以下情况:
短转移:IP的修改范围为-128字节~127字节(2的8次方,8位)
近转移:IP的修改范围为-32768字节~32767字节(2的16次方,因为在8086中IP寄存器为16位)

  • jmp short 标号(转到标号处执行命令)
    这种格式的jmp指令实现的是上述的段内短转移,修改范围为-128~127;
    该条指令执行后,CS:IP指向标号处的指令。编写代码如下图:

可以看到在对汇编程序进行编译后,jmp short s转换成了jmp [标号所在位置IP的值],在这里为什么我们看到JMP 0008的机器码为EB03,03h确实是偏移量。这里可以理解为是针对jmp指令下一跳指令的偏移量(因为CPU的执行过程为:从CS:IP将指令读入指令缓冲区,然后IP指向下一条指令,然后CPU才执行缓冲区jmp指令。也就是说将jmp short s读入缓冲区后,CS:IP已经指向0B86:0005,所以偏移量针对0005为03h)。

  • 2.jmp near ptr 标号(转到标号处执行命令)
    这种格式的jmp指令实现的是上述的段内近转移,在跳转范围大于-128~127时使用jmp short会编译失败。

db 128 dup(0)的作用就是创建 128个字节的0,为了使s标号的偏移超过127(在这里需要注意,编译时自动将我们创建的128个字节编译成为指令)

可以看到 偏移量为0080h,也就是128,从0006偏移80h,那么刚好是0086h,我们查看0B86:0086处的内容确实是我们所期待的

  • 3.jmp far ptr 标号(转到标号处执行命令)
    这种格式的jmp指令实现的是上述的段间转移,同时修改CS和IP,在跳转范围大于-32768~32767时使用jmp near ptr不会编译失败,但是会链接失败。
    该指令执行后CS:IP将同时修改,将代码修改为如下图:

到EA后面前四位为IP要改的值为(注意此时该值不再是针对与下一条指令的偏移量,而直接是要修改的值)8008h,后四位为CS要改的值0B86h,CS还是0B86h的原因很简单,因为向前偏移8008h并未超出FFFF,因此段地址未发生变化

  • 4.另外常见的jmp指令还有 jmp [16位寄存器](如 jmp ax),该指令功能是将IP修改为16位寄存器的值。
    Jmp word ptr 段寄存器:[偏移]如(jmp word ptr ds:[0]),该指令的功能是将IP修改为内存单元中所存的一个16位字