当前位置: 汇编教程 > 04-转移指令 > 阅读正文

汇编 jmp指令

2021.7.12.   455 次   1303字

jmp为无条件转移, 可以只修改IP, 也可以同时修改CS:IP

jmp指令要给出两种信息:

  • 转移的目的地址
  • 转移的距离( 段间转移, 段内短转移, 段内近转移)

语法格式:

  • jmp short 标号 ==> 短转移, 指定修改IP范围-128~127 ( 8位 )
  • jmp near ptr 标号 ==> 近转移, 修改ip范围-32769~32767 ( 16位 )
  • jmp far ptr 标号 ==> 段间转移, 也叫远转移,

短转移实例

code segment
    assume cs:code
start: 
    mov ax, 0
    jmp short s
    add ax, 1
    s:
        inc ax
code ends
end start

上述代码从jmp直接跳到了s, 所以结果ax为1

汇编指令, 可以翻译为机器码, 例如

汇编指令机器指令
mov ax, 0123B8 23 01
mov ax, ds:[0123]A1 23 01
push ds:[0123]FF 36 23 01

汇编指令中, 操作码和数据( 或地址 ), 是分开的, 例如可以看到ax对应B8, 而0123则原封不动

当我们使用 debug 调试jmp短转移程序时, 使用 u 翻译指令, 会同时得到机器码和指令, 但我们发现, jmp 0008 的机器码为 EB03, 即cpu并不知道cs:ip

修改短转移程序, 在add ax, 1后一句增加一个add ax, 1然后再调试时, 发现得到的是jmp 000B对应 EB06, 我们发现了cpu不需要cs:ip就可以实现转移, 而它是根据偏移地址取得的, 一句add ax, 1是3个字节( 机器码050100 ), 那么2句重复就是06, 它的机器码( 操作码EB, 数据06)

jmp短转移中, 简记为 ip = ip + 偏移, 地址的 -128~127是补码形式

如果跳转的标号, 在当前指令前面, 即偏移为负数时, 是否死循环? 为何不使用cs:ip转移? 在实际程序中cs:ip是否会变化而导致跳转失败?

远转移实例

短转移, 近转移语法非常相似, 几乎没有区别, 而远转移却相差甚远

jmp far ptr 标号, 需要使用 cs:ip 指定转移的cs:ip ( 如果少于128, 则会自动变成短转移)

这里, 使用dup开辟一个128单位空间, 确保它跳转的超过128, 否则会自动变为短转移

code segment
    assume cs:code
start: 
    mov ax, 0
    jmp far ptr s
    db 128 dup(0)
    add ax, 1
    s:
        inc ax
code ends
end start

使用debug得到的指令, jmp 076c:008b, 对应的机器码为 EA8B006C07

在这里, 076c表示 cs, 而 008b则是ip, 可以看到跳转的确实是cs:ip, 而不是偏移地址

jmp的其他用法

jmp还有其他语法, 例如

  • jmp 16位寄存器 ( 如: jmp ax, ax中存放了ip )
  • jmp 内存地址 ( 重点介绍 )

在内存中使用jmp, 有以下两种语法

  • jmp word ptr 内存单元(16位段内转移, 只能是ip)
  • jmp dword ptr 内存单元地址( 双字, 32位, 段间转移)

需要注意, 高位cs, 低位ip, 那么内存中实际是, ip, cs ( ip=内存地址, cs=内存地址+2)

以下实例, 将跳转到 0:0123H

mov ax, 0123H
mov ds:[0], ax
mov word ptr ds:[2]
jmp dword ptr ds:[0]

本篇完,还有疑问?

加入QQ交流群:11500065636 IT 技术交流群