jmp指令原理详解篇(无条件转移指令)

1 初步理解

   在8086汇编中,cpu要执行指令之前必须先取指(把指令从内存传输到cpu中),从而必须要给出指令所在内存单元的物理地址,寄存器cs:ip就是这个物理地址所对应的段地址和偏移地址(段地址16+偏移地址=物理地址*),而jmp指令就是用来修改ip或者cs和ip的内容,使cpu执行jmp所指向的那条指令(发生跳转/转移),不会执行原定顺序的下一条指令。所以jmp指令要给出两个信息,如下:

  • jmp指令要给出两种信息:
    • 1.转移的目的地址
    • 2.转移的距离/偏移地址(距离不同转移的类型不同)
      • 段间转移(远转移):同时修改cs和ip
      • 段内短转移:jmp short 标号 ;只修改ip的值,ip的修改范围为-128~127(负数跳转方向是jmp指令之前,否则是之后),8位的位移
      • 段内近转移:jmp near ptr 标号 ;只修改ip的值,ip的修改范围为-32768~32767,16位的位移

例如:
在这里插入图片描述

2 jmp指令格式(小总结)

指令格式示例
jmp 标号-段间转移(远转移):jmp far ptr 标号
-段内短转移:jmp short 标号 ;8位的位移
-段内近转移:jmp near ptr 标号 ;16位的位移
jmp 寄存器-jmp bx ;等价于段内近转移,也是16位的位移
jmp 内存单元(用地址表示的)-jmp word ptr 内存单元地址 ;段内转移
-jmp dword ptr 内存单元地址 ;段间转移

备注:在源程序中,不能直接使用“jmp 2000:0100"这样的转移指令来实现段间转移,这种方式在debug模式中使用的汇编指令,在源程序中写,编译器并不识别(编译报错)

3 jmp指令本质-详解

3.1 引子

我们使用debug模式进行观察可以了解,常见指令中的立即数在机器指令中有所体现,意思是像mov ax,0123、mov ax,[123]、push [0123]这样使用立即数的指令,其编译后的机器码中带有立即数,如下(debug模式中)
在这里插入图片描述
    图中两种颜色的标注可知,常用指令所带的立即数在编译后对应的机器码中有所体现(包含在机器码中)
(备注:在debug模式中直接使用 ”指令名称 [立即数]“ 这种写法,在源程序中这样写会存在问题)

3.2 jmp short 标号(jmp short s为例) 怎么转移指令的?

源代码:

assume cs:codesg
codesg segment
start:		mov ax,0
			jmp short s                ;执行完jmp后程序从inc ax处开始执行
			add ax,1                   ;不被执行
	S:		inc ax
	      	mov ax,4c00h
			int 21h
codesg ends
end start

debug模式下的机器码:
在这里插入图片描述
  由上图红色标注,源程序中jmp指令编译后对应的机器码为"EB03",发现这个机器码中的并不像前面我们所说的那样把jmp后面的”0008“体现在机器码中,而是一个”03“的数值代替,那是因为这个”03“就是jmp将要跳转到的那条指令的地址(076A:0008)相对于jmp指令的下一条指令地址(076A:0005)的偏移地址(位移的距离)。即”跳转目的地的指令的偏移地址(0008) = jmp下一条指令的偏移地址(0005)+jmp机器码包含的”03“偏移量“。为什么会是这样?因为当执行jmp时,会先进行取指(把jmp这条指令从内存取出送入到cpu中),之后接着ip自增,指向下一条指令(ip=0005),然后由控制执行器执行jmp,发现jmp是转移指令,因此修改ip,即ip = ip + 03(ip=0008),所以执行完jmp后,cs:ip = 076A:0008,jmp就实现了程序的跳转。

备注:上面记录的是段内短转移(cs未变),jmp的其他类型转移都大同小异,修改ip或者cs:ip的值

4 总结

  偷个懒…就先这样~哈【尴尬】

8086汇编环境资源免费获取【DOSBox】
链接:https://pan.baidu.com/s/1aRv4k6DVlJtGkHQDB6WjrA
提取码:8086

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐