假设我想使用以下操作码进行短暂跳转:


EB CB或JMP rel8

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

(其中CB是一个字节带符号的值,表示与EIP寄存器中的方向有关的相对偏移)


偏移量可能总是偏移量+2,因为在此短暂跳转中执行时间(参考方向)中的EIP是双字节指令的基础,但是加数occurs always


eb 30 = jmp 0x00000032(+30)

eb e2 = jmp 0xffffffe4(-30)

则EIP可能会故意朝着同一方向,因为fe + 2为00或EIP。

eb fe = jmp 0x00000000


我发现令人惊讶的是,尽管偏移量为负,但发生了偏移。但是在Intel中我没有提及(也许是因为3000页)。


英特尔®64和IA-32架构
软件开发人员手册:第一卷2A 3-423


近距离跳跃,其跳跃范围从当前EIP值限制为–128至+127。



然后,我考虑了三种可能性:


是+2,因为它是执行时间中EIP的after / future值
编码值不是2s组件编码的带符号数字。
这出现在手册中,但我没有看到,因为我很愚蠢

最佳答案

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指令本身显示它。这可能会引起一些混乱。

关于assembly - 如何在x86中编码相对较短的jmp,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14889643/

10-12 07:25