You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86汇编调用C函数编译报错求助:_start重定义与main未定义

Fixing Multiple Definition of _start and Undefined main Errors When Linking Assembly with GCC

Hey there, let's walk through why you're hitting these errors and how to fix them:

First, let's unpack the errors:

  • multiple definition of '_start': When you use gcc to compile/link your assembly code, it automatically links in the C runtime (CRT) libraries. The crt1.o file from the CRT already defines _start as the program's entry point. If your assembly code also defines _start, the linker sees two identical symbols and throws this conflict error.
  • undefined reference to 'main': The CRT's _start function is designed to call a main function as the actual entry point of your program. Since your code doesn't have a main symbol, the linker can't resolve this reference.

Solution 1: Use main as your assembly entry point (simplest approach)

Modify your assembly code to use main instead of _start as the entry, and declare it as global so the linker can find it. This plays nicely with the C runtime:

section .data
    msg db 'Hello from printf!', 0x0a, 0  ; Null-terminated string for printf

section .text
    global main       ; Declare main as global
    extern printf     ; Tell assembler about the C printf function

main:
    mov rdi, msg      ; First argument (format string) in rdi (x86_64 calling convention)
    mov rax, 0        ; RAX = number of floating-point arguments (0 here)
    call printf       ; Call the C printf function
    
    mov rax, 0        ; Return 0 (success) to the CRT
    ret

Compile with your original command:

gcc helloC.s -o hello

This works because the CRT's _start will call your main function, and there's no conflict over the _start symbol.


Solution 2: Keep _start and skip the C runtime

If you want to stick with _start as your entry point, you need to tell GCC not to link the CRT with the -nostartfiles flag. You'll also need to manually call the C exit function to properly terminate the program (otherwise it'll crash):

section .data
    msg db 'Hello from printf!', 0x0a, 0

section .text
    global _start
    extern printf
    extern exit       ; Need this to exit cleanly

_start:
    mov rdi, msg
    mov rax, 0
    call printf
    
    mov rdi, 0        ; Exit code 0 (success)
    call exit         ; Call C exit function to terminate

Compile with this command:

gcc -nostartfiles helloC.s -o hello

This skips the CRT's _start definition, so your custom _start is used instead.


A quick note on x86_64 calling conventions: When calling printf, the first argument goes in rdi, and you need to set rax to the number of floating-point arguments passed (0 in this case, since we're just passing a string).

内容的提问来源于stack exchange,提问作者Fenrir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:36:27