【问题标题】:Forcing a JMP rel32强制执行 JMP rel32
【发布时间】:2022-12-17 13:51:51
【问题描述】:

如果我做类似的事情(虚拟示例):

jmp 1f
1: ret

在 gcc/clang 上,它会生成一个较短的相对跳转,因为标签就在附近。

我很好奇,无论标签的距离如何,都可以强制使用 JMP rel32 吗?

【问题讨论】:

  • @msaw328 谢谢。我会处理的。
  • 您可以通过手动构建 jmp rel32 以一种骇人听闻的方式模拟它(您可以通过将其放入宏中来改进它):.byte 0xe9.long (1f - 4) - .1: ret
  • @MichaelPetch 喜欢它的蛮力。谢谢!
  • 作为参考,NASM 允许jmp strict near ...

标签: assembly x86-64 att


【解决方案1】:

根据GAS manual,第 9.16.8 节“跳转指令始终经过优化以使用尽可能小的位移”。这似乎暗示没有手动方法可以覆盖它。 9.16.6 中有 addr32 指令前缀,但只允许在.code16 中使用。我似乎无法找到一个选项来控制任何“官方”来源中 jmp 偏移量的大小。

但是,根据 this source 将跳转到的标签标记为全局将使 jmp 指令使用 rel32 偏移量。虽然我只是设法使用 clang 重现了该行为,但 GCC 似乎不起作用。此外,对于这种行为,我似乎找不到比上述 15 年前的讨论更可靠的来源,所以我不会确切地将其称为“可靠”。我认为它可能会随着未来对 clang/llvm-as 的更新而被忽视。

例如,以下文件test_asm.s

.global main
main:
jmp lab
.global lab
lab: ret

在我的机器上用 clang test_asm.s 编译结果:

000000000000111c <main>:
    111c:   e9 00 00 00 00          jmp    1121 <lab>

0000000000001121 <lab>:
    1121:   c3                      ret

同时,在删除 .global lab 行后,结果是:

000000000000111c <main>:
    111c:   eb 00                   jmp    111e <lab>

000000000000111e <lab>:
    111e:   c3                      ret

对于可靠但繁琐的解决方案,您始终可以手动将 jmp 指令编码为字节,然后使用 .byte 指令代替 jmp &lt;operand&gt; 助记符输入它们,如 cmets 中所指出的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多