assembly 如何在x86中编码相对较短的jmp

czfnxgou  于 2023-01-21  发布在  其他
关注(0)|答案(3)|浏览(139)

假设我想使用EB操作码jmp rel8 short jump执行一个短跳转
Intel manual entry for it

    • EB***CB * 或 * JMP版本8 *

短跳转,RIP = RIP+扩展到64位的8位位移符号
(其中CB是字节有符号值,表示与EIP寄存器中的方向相关的相对偏移)
偏移量可能总是 * offset +2 *,因为在该短跳转中执行时间(参考方向)中的EIP是二字节指令的基址,但是加数occurs always

  • eb 30 = jmp 0x00000032 (+30)
  • eb e2 = jmp 0xffffffe4 (-30)

则EIP可以有意地为相同方向,因为fe +2是00EIP

  • eb fe = jmp 0x00000000

我觉得令人惊讶的是,* overoffset * 发生分叉,虽然数字是负的。但在英特尔我发现没有提到(可能是因为3000页)。

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

近跳转,跳转范围限制在当前EIP值的-128到+127之间。
我考虑了三种可能性:
1.为+2,因为是执行时间内EIP的 * 之后/未来值 *
1.编码值不是2s分量编码的有符号数字。
1.这出现在手册中,但我没有看到,因为我很愚蠢

0vvn1miw

0vvn1miw1#

不管是不是跳远,都是destination - (source + sizeof(instruction))
dst - end_of_jmp
在您的例子中(短跳),sizeof(instruction)为2。
添加此值的原因是因为一旦CPU执行了取指令阶段,指令指针就已经指向分支之后的指令。rel 8或rel 32分支位移与EIP/RIP值相关。

kuarbcqp

kuarbcqp2#

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

prdp8dxp

prdp8dxp3#

短跳转取相对于跳转指令的 end 的EIP(2字节长),并取1字节操作数,该操作数经过符号扩展后加到EIP。

相关问题