【发布时间】:2017-02-17 15:37:34
【问题描述】:
我有一个带有_start 标签的程序集文件作为.text 段中的第一件事。我希望这个标签成为我的应用程序的入口点。
每当我将此文件与另一个具有称为main 的函数的文件一起传递时,无论如何,main 函数最终都会成为我的应用程序的入口点。
我正在使用 GNU 链接器并尝试了 -e _start 标志,以及更改输入文件顺序。只要存在main 函数,它将成为入口点。如果我重命名main 函数,它工作正常,我的_start 标签成为入口点。
编辑:似乎是因为编译器的-O2 标志。
as.s
.text
.global _start
_start:
jmp main
main.c
int main(){
return 0;
}
编译
gcc -O2 -c as.s -o as.o
gcc -O2 -c main.c -o main.o
ld -e _start as.o main.o -o test
输出
00000000004000b0 <main>:
4000b0: 31 c0 xor %eax,%eax
4000b2: c3 retq
00000000004000b3 <_start>:
4000b3: e9 f8 ff ff ff jmpq 4000b0 <main>
有什么想法吗?
【问题讨论】:
-
您忘记发布任何证明,也没有版本或环境信息,也没有minimal reproducible example。我已经测试过了,效果很好。
-
您确实意识到,仅仅因为
main出现在_start之前,它就不是入口点,对吧?入口点在 ELF 标头字段中给出。 -
那种。无论如何,我需要 _start 标签位于可执行区域的开头。不过,
-O1和-O0似乎可以正常工作。 -
您是否需要在文件的开头使用它,因为您正在使用引导加载程序加载它并且您打算 JMP/CALL 到它。要求将
_start之类的特定标签放在特定位置对我来说,这比表面上看到的要多。 -
如果我想让一个特定的函数成为可执行文件中的第一件事,我会将它放在它自己的部分中,并创建一个链接描述文件,在开始时定位该部分。