【问题标题】:JMP instruction - Hex codeJMP 指令 - 十六进制代码
【发布时间】:2012-04-06 14:39:53
【问题描述】:

对JMP机器指令的十六进制码转换有疑问。我有我想跳转到的绝对地址,比如“JMP 0x400835”。 首先,这是允许的吗?如果是,那么对应的十六进制代码是什么? 如果没有,我可以先将地址存储在某个寄存器中,比如 EAX,然后输入“JMP EAX”吗? 我正在研究 x86(64b) 架构。

我尝试从gdb中的diassem输出中打印出十六进制代码,但是没有一致性,即在十六进制代码中看不到目的地址。

我是十六进制代码和机器指令的新手,请原谅我的无知。

【问题讨论】:

标签: assembly hex x86-64 machine-code


【解决方案1】:

如果您出于某种原因不想使用寄存器,也可以将 64 位绝对立即跳转编码为

ff 25 00 00 00 00           jmp qword ptr [rip]      jmp *(%rip)
yo ur ad dr re ss he re     some random assembly

rip 指的是 jmp 指令本身之后的指令指针,因此它是指向您的地址的指针。

【讨论】:

    【解决方案2】:

    在 64 位模式下,没有 JMP absaddr 形式的跳转到绝对地址。跳转的操作数始终是相对于rip 的 32 位相对位移,其符号扩展为 64 位。

    您看到不一致的原因可能是偏移量取决于当前指令指针,而您没有意识到这一点。

    jmp eax 也是不允许的,因为在 64 位架构上地址当然总是 64 位宽。一个序列mov rax, addr + jmp rax 是可能的,它看起来像

    48 c7 c0 35 08 40 00            mov rax, 0x00400835
    ff e0                           jmp rax
    

    或

    48 b8 35 08 40 00 00 00 00 00   mov rax, 0x0000000000400835
    ff e0                           jmp rax
    

    我是怎么知道这些十六进制代码的?好吧,我确实问过我的编译器。我用gcc -c 编译并用objdump 反汇编。我没有费心使用 Intel 语法,因为我不需要它。所以这是 AT&T 语法。

    echo 'asm("mov $400835, %rax\n jmp *%rax\n");' > test.c
    gcc -c test.c
    objdump -d test.o
    

    【讨论】:

    • 感谢您的回答。这真的帮助了我。 objdump 真的是个好工具!
    • 嘿..我已将您的帖子标记为“有用”..我猜这就是需要的,对吧?
    • 您的意思是“jmp absaddr”将是“jmp %rip + absaddr”(其中 absaddr 必须等于或小于 32 位)?
    • @ManofOneWay 也不确定您要问什么,因为没有 jmp absaddr 和 jmp %rip+absaddr 不是绝对的。如果您告诉汇编器以jmp someaddr 的形式翻译一些代码,它将计算从当前地址(稍后将在%rip)到someaddr 的相对距离并发出e9 xx xx xx xx,其中四个 xx 字节对应计算出的地址差。
    • 这里写“jmp *%rax”。你能告诉我在哪里可以找到这种语法的描述吗?因为到处都解释了 AT&T 语法,所以没有列出这个 JMP 语法。
    猜你喜欢
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 2019-01-01
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多