如果我做类似的事情(虚拟示例):
jmp 1f
1: ret
在 gcc/clang 上,它会生成一个短的相对跳转,因为标签很近。
我很好奇,无论标签的距离如何,是否可以强制
JMP rel32
?
根据GAS手册,第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 <operand>
助记符输入它们,如注释中所指出的。