【问题标题】:How to compile assembly whose entry point is not main with gcc?如何使用 gcc 编译入口点不是 main 的程序集?
【发布时间】:2026-02-15 11:50:02
【问题描述】:
.text
    .globl _start
_start:
     pushq %rbp
     movq %rsp,%rbp
     movq $2, %rax
     leaveq
     retq

我正在编译 -nostdlib:

[root@ test]# gcc -nostdlib -Wall minimal.S &&./a.out 
Segmentation fault

这里有什么问题?

顺便说一句,是否可以将入口点设为main_start 以外的名称?

【问题讨论】:

    标签: gcc assembly x86-64


    【解决方案1】:

    正如@jaquadro 提到的,您可以在命令行上指定链接器的入口点(或使用链接脚本):gcc -Wall -Wextra -nostdlib -Wl,-eMyEntry minimal.S && ./a.out

    您的程序段错误的原因是,由于您没有使用标准库,因此无处可返回 (retq)。而是使用正确的系统调用调用 exit(在本例中为 60,将其放入 rax,第一个(也是唯一的)参数放入 rdi

    例子:

    。文本 .globl 我的条目 我的条目: # 使用 Syscall 60 (exit) 以错误代码 42 退出 movq $60, %rax movq $42, %rdi 系统调用

    Related question on how to perform syscalls on x86_64

    【讨论】:

    • 顺便说一句,通过实验我发现retqret功能相同,是真的吗?
    • 在这种情况下,是的。 qsize suffix 和 x86_64 中的默认大小,所以这里可能是多余的。
    【解决方案2】:

    您可以通过将选项传递给链接器来设置入口点

    http://sca.uwaterloo.ca/coldfire/gcc-doc/docs/ld_24.html

    要使用 gcc 执行此操作,您需要执行类似...

    gcc all_my_other_gcc_commands -Wl,-e,start_symbol
    

    main 不同,它不是你编译的应用程序的入口点,尽管它是从入口点调用的函数。如果您正在编译 C 或 C++ 代码,则入口点本身在 glibc 源代码树的 Start.S 之类的深处定义,并且与平台相关。如果您正在编程直接汇编,我不知道实际发生了什么。

    【讨论】:

    • @je-rog 再次检查命令,我在选项中有错字(-Wl 与 -W)。我的免责声明是我已经用 C 代码完成了所有这些,我希望至少 entry 选项应该仍然是相关的。 -Wl 旨在将选项传递给链接器。
    • 还是无效,你可以试试看。
    • @je-rog 我很抱歉我的语法生疏了,我再次更新了,这次我已经测试过了。非常挑剔。