2013-02-15 60 views
13

假设我想用下面的操作码做一个短跳转:如何编码在x86的相对短JMP

EBCBJMP发布8

“跳转短,RIP = RIP + 8位移位符号 扩展到64位“

(其中CB是字节有符号值表示与方向EIP寄存器)

也许始终偏移将是相对偏移偏移+ 2因为(EIP的执行时间基准方向)在这个短跳跃的基的twobyte指令,但加数occurs always

EB 30 = JMP 0x00000032(30)

EB E2 = JMP 0xffffffe4(-30)

然后EIP可以故意地是相同的方向,因为fe + 2是或EIP

EB FE = JMP 00000000

我觉得奇怪的是,overoffset内容时发生分叉,虽然数量是负的。但在英特尔我没有发现(也许是因为3000页)。

英特尔®64和IA-32体系结构 软件开发人员手册:卷。图2A 3-423

的近跳,其中跳转范围是从当前 EIP值不限于-128至127

然后我考虑三种可能性:

  1. 是2因为是后在执行时间EIP的/未来值
  2. 的编码值不是编码的2S部件签署数。
  3. 这似乎在手册中,但我还没有看到,因为我傻

回答

11

rel8是相对于下一个指令的存储器地址,因为可以很容易地通过创建两个可执行和拆卸它们予以确认:

@label: 
    jmp @label 
    nop 

这拆解如(与ndisasm,它在16位是相同的, 32位和64位代码):

EBFE jmp short 0x0 
90 nop 

然后,另一个可执行:

jmp @label 
@label: 
    nop 

EB00 jmp short 0x2 
90 nop 

因此,rel8总是相对于jmp之后的下一条指令进行编码。然而,反汇编器(至少ndisasmudcli)显示它相对于jmp指令本身。这可能会导致一些混淆。

14

无论是短跳与否,它总是destination - source + sizeof(opcode)。在你的情况下(无条件短跳转),sizeof(opcode)是2.这个增加的原因是因为一旦cpu执行了取指令阶段,指令指针就会指向分支之后的指令。

+0

我很困惑的术语:什么是“短跳”?我一直无法在网络上的任何地方找到这个定义。 – 2013-02-20 19:30:40

+2

@AndersonGreen短跳转编码为* jmp rel8 *(EB XX),其中相对距离(dest-source)小于0x80。另一个叫做跳远,它编码为* jmp rel32 *(E9 XXXXXXXX)。请注意,这可以使用66H前缀进行编码,这会将操作数更改为* rel16 *。 – JosephH 2013-02-21 06:24:28

4

跳转指令相对于跳转指令的结束(它是两个字节长)需要一个EIP,并且需要一个字节的操作数,它是符号扩展并添加到EIP。