强制 JMP rel32 (JMPQ)

PSk*_*cik 5 assembly x86-64 att instruction-encoding

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

jmp 1f
1: ret
Run Code Online (Sandbox Code Playgroud)

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

我很好奇,是否可以强制 aJMP rel32无论标签的距离如何?

Mac*_*iej 5

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

但是,根据此来源,将您跳转到的标签标记为全局将使jmp指令使用rel32偏移量。我只能使用 clang 重现该行为,但 GCC 似乎不起作用。此外,对于这种行为,我似乎找不到比上述 15 年前的存档邮件列表回复更可靠的来源,因此我不会确切地称其为“可靠”。我认为,随着未来对 clang/llvm-as 的更新,它可能会被忽视。

例如,以下文件test_asm.s

.global main
main:
jmp lab
.global lab
lab: ret
Run Code Online (Sandbox Code Playgroud)

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

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

0000000000001121 <lab>:
    1121:   c3                      ret
Run Code Online (Sandbox Code Playgroud)

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

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

000000000000111e <lab>:
    111e:   c3                      ret
Run Code Online (Sandbox Code Playgroud)

为了获得可靠但乏味的解决方案,您始终可以手动将jmp指令编码为字节,然后使用指令代替助记符输入它们.bytejmp <operand>如注释中所指出的。

  • 谢谢。最终得到 Michael Petch 的解决方案:`#define MY_asm_jmpq(Target) .byte 0xe9; .long ((Target) - 4) - .` (我使用 C 宏。我将宏字符串化 asm 放入我的 C 源代码中,并在适当的情况下在 asm 内部使用 C 宏)。我发现可靠比解决汇编器怪癖更简单。 (3认同)
  • 我必须使用 VASM 来完成 68000 装配。我的中断代码崩溃了,因为汇编器正在将“JSR”优化为“BSR”(绝对调用与相对调用),并且它弄乱了我的中断处理程序(它们被复制到 RAM 以避免切换情况的开销) (2认同)