如何防止 GNU ld 重新排序目标文件?

How to prevent GNU ld from reordering the object files?

我在分布于多个 .s 文件的 i386 程序集中实现了一个函数。函数的结果取决于机器码连接的顺序,例如:

$ gcc -m32 -Wl,-N -W -Wall -Werror -s -O2 -o calladd calladd.c add10.s double.s add1.s ret.s && ./calladd a b; echo $?
27
$ gcc -m32 -Wl,-N -W -Wall -Werror -s -O2 -o calladd calladd.c add10.s add1.s double.s ret.s && ./calladd a b; echo $?
28

我总是希望 ret.s 中的代码最后(因为它包含 ret 指令),并且我想改变其他 .s 文件的顺序。

如何确保 GNU ld 按照我指定的顺序发出代码 .s 文件?它似乎默认工作,但我希望解决方案更具弹性,即明确禁用对这些 .s 文件的重新排序,即使为其他文件启用重新排序也是如此。哪些命令行标志是相关的?

我最好不要链接描述文件。

我的示例文件是:

# calladd.c:
extern int add10(int) __attribute__((regparm(1)));
int main(int argc, char **argv) { (void)argv; return add10(argc); }

# add10.s:
.text
.globl add10
add10:
addl , %eax

# add1.s:
.text
.globl add1
add1:
addl , %eax

# double.s:
.text
.globl double
double:
addl %eax, %eax

# ret.s:
.text
ret

根据@RossRidge 的评论:默认情况下,GNU ld 不会重新排序源文件,只需依赖它即可。为了避免因为对齐而插入额外的字节,不要在 .s 文件中使用 .align 或任何类似的东西,并将它们放在同一部分 .text.