x86汇编调用C函数编译报错求助:_start重定义与main未定义
_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 usegccto compile/link your assembly code, it automatically links in the C runtime (CRT) libraries. Thecrt1.ofile from the CRT already defines_startas 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_startfunction is designed to call amainfunction as the actual entry point of your program. Since your code doesn't have amainsymbol, 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

