如果我做类似的事情(虚拟示例):
jmp 1f 1: ret
字符串在gcc/clang上,它生成一个短的相对跳跃,因为标签很近。我很好奇,有没有可能强制JMP rel32,而不管标签的距离?
JMP rel32
nfg76nw01#
根据GAS manual,第9.16.8节“跳转指令总是被优化为使用最小可能的位移”。这似乎意味着没有手动的方法来覆盖它。在9.16.6中有一个addr 32指令前缀,但它只允许在.code16中使用。我似乎找不到一个选项来控制jmp偏移量的大小。“官方”来源。然而,根据this source,将跳转到的标签标记为global将使jmp指令使用rel32偏移量。我只设法使用clang再现了该行为,但GCC似乎不起作用。此外,我似乎找不到任何更可靠的来源,这种行为比提到的15岁的存档邮件列表答复,所以我不会确切地称之为“我想它可能会在未来对clang/llvm-as的更新中被忽视。例如,以下文件test_asm.s:
.code16
jmp
rel32
test_asm.s
.global main main: jmp lab .global lab lab: ret
字符串在我的机器上用clang test_asm.s编译的结果是:
clang test_asm.s
000000000000111c <main>: 111c: e9 00 00 00 00 jmp 1121 <lab> 0000000000001121 <lab>: 1121: c3 ret
型同时,删除.global lab行后,结果是:
.global lab
000000000000111c <main>: 111c: eb 00 jmp 111e <lab> 000000000000111e <lab>: 111e: c3 ret
型对于一个可靠的解决方案,尽管是一个繁琐的解决方案,您可以始终手动将jmp指令编码为字节,然后使用.byte指令代替jmp <operand>助记符输入它们,如注解中所指出的那样。
.byte
jmp <operand>
1条答案
按热度按时间nfg76nw01#
根据GAS manual,第9.16.8节“跳转指令总是被优化为使用最小可能的位移”。这似乎意味着没有手动的方法来覆盖它。在9.16.6中有一个addr 32指令前缀,但它只允许在
.code16
中使用。我似乎找不到一个选项来控制jmp
偏移量的大小。“官方”来源。然而,根据this source,将跳转到的标签标记为global将使
jmp
指令使用rel32
偏移量。我只设法使用clang再现了该行为,但GCC似乎不起作用。此外,我似乎找不到任何更可靠的来源,这种行为比提到的15岁的存档邮件列表答复,所以我不会确切地称之为“我想它可能会在未来对clang/llvm-as的更新中被忽视。例如,以下文件
test_asm.s
:字符串
在我的机器上用
clang test_asm.s
编译的结果是:型
同时,删除
.global lab
行后,结果是:型
对于一个可靠的解决方案,尽管是一个繁琐的解决方案,您可以始终手动将
jmp
指令编码为字节,然后使用.byte
指令代替jmp <operand>
助记符输入它们,如注解中所指出的那样。