jmp进行跳转
根据位移进行的转移
用jmp进行跳转时,会发现一个奇怪的问题,无论它要跳转到哪里,它的机器码始终不变,为EB03,那么它到底是怎么告诉cpu修改ip地址的呢?
先回忆一下cpu读取指令的过程
- cs=076a ip=0006,cs:ip指向eb03
- 读取指令码eb03到指令缓冲器
- ip=ip+指令长度=0008h,cs:ip指向下一条指令
- cpu执行指令缓冲器中的指令eb03
- 执行完缓冲器中的指令后,ip被修改+
jmp指令并不需要转移的目的地址,但是它是凭借什么转移的呢?这里有个03,正好跳过三个字节之后就是要转移的地址。原来jmp指令只需知道当前指令的下一个指令(因为执行完这条指令后ip会增加)与要跳转的指令的位移就可以了
jmp short 标号 功能是 ip=ip+8位位移(一字节)
jmp near ptr 标号 是16位
jmp far ptr 标号 是段间转移,可以修改cs
还可以直接 jmp 寄存器1:寄存器2
根据内存进行的转移
转移地址再内存中的转移有两种格式
- jmp word ptr(段内转移)
例 jmp word ptr ds:[0]
jmp word ptr [bx]
2.jmp dword ptr (段间转移)后面接两个字,第一个是偏移地址,第二个是段地址
例 jmp dword ptr ds:[0],0 完成后段地址为0
注意cs:code
code
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个字节