根据位移进行的转移

用jmp进行跳转时,会发现一个奇怪的问题,无论它要跳转到哪里,它的机器码始终不变,为EB03,那么它到底是怎么告诉cpu修改ip地址的呢?

先回忆一下cpu读取指令的过程

  1. cs=076a ip=0006,cs:ip指向eb03
  2. 读取指令码eb03到指令缓冲器
  3. ip=ip+指令长度=0008h,cs:ip指向下一条指令
  4. cpu执行指令缓冲器中的指令eb03
  5. 执行完缓冲器中的指令后,ip被修改+

jmp指令并不需要转移的目的地址,但是它是凭借什么转移的呢?这里有个03,正好跳过三个字节之后就是要转移的地址。原来jmp指令只需知道当前指令的下一个指令(因为执行完这条指令后ip会增加)与要跳转的指令的位移就可以了

jmp short 标号 功能是 ip=ip+8位位移(一字节)

jmp near ptr 标号 是16位

jmp far ptr 标号 是段间转移,可以修改cs

还可以直接 jmp 寄存器1:寄存器2

根据内存进行的转移

转移地址再内存中的转移有两种格式

  1. jmp word ptr(段内转移)

例 jmp word ptr ds:[0]

jmp word ptr [bx]

2.jmp dword ptr (段间转移)后面接两个字,第一个是偏移地址,第二个是段地址

例 jmp dword ptr ds:[0],0 完成后段地址为0

注意

assume cs:code

code segment
mov ax,4c00h
int 21h
start:
mov ax,0
s: nop
nop

mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax
s0: jmp short s
s1: mov ax,0
int 21h
mov ax,0
s2: jmp short s1
nop
code ends
end start

这个程序奇怪之处在于运行到mov cs:[di],ax后 s处会变为jmp 0000,这里就要记住jmp传递的是偏移地址,也就是说,jmp short s1这个指令并不是真的跳到s1处,而是往前跳8个字节