【发布时间】:2021-01-27 05:00:21
【问题描述】:
我用 C 语言编写了一个 Hello World 程序。我使用命令 gcc -S -o hello.s hello.c(代码在 hello.c 中)生成汇编,然后使用 as 汇编它。最后我使用ld链接了目标代码,但它给了我以下错误:
ld: a.out:hello.c:(.text+0xa): undefined reference to `__main'
ld: a.out:hello.c:(.text+0x16): undefined reference to `puts'
C 代码如下:
#include <stdio.h>
int main(void) {
printf("Hello world!\n");
}
我使用 Intel Core i3 处理器,并使用 MinGW 进行编译。我的操作系统是 Windows 7。
这是生成的程序集:
.file "hello.c"
.text
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "Hello world!\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB13:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
call ___main
movl $LC0, (%esp)
call _puts
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE13:
.ident "GCC: (MinGW.org GCC Build-2) 9.2.0"
.def _puts; .scl 2; .type 32; .endef
【问题讨论】:
-
如果你想让
main和printf工作,你还需要系统的C 库,而不仅仅是libgcc。如果您使用gcc -v进行链接,您将看到正在运行的完整的血腥ld命令。对于任何给定的程序,您可能不需要所有这些,但您至少需要了解它们的作用以及哪些部分是必要的。 -
___main(C name__main) 是 MinGW 初始化其 libc 的方式,而不是使用动态链接器挂钩来让代码运行 beforemain(或甚至在_start之前),就像 glibc 在 GNU/Linux 上所做的那样。