自定义编译器链接时出现ld警告:无法找到入口符号_start
解决ld找不到_start入口符号的问题
先查汇编代码里的_start定义
- 必须给
_start加全局可见声明:汇编里一定要有.global _start,不然哪怕写了_start:,ld也识别不到这个符号。正确写法示例:.global _start _start: # x86_64架构下的退出系统调用代码 mov $60, %rax mov $0, %rdi syscall - 检查拼写:别把
_start写成start(缺下划线)或者_START(大小写错误),Linux下ld对符号大小写敏感。
用gcc链接的正确姿势
gcc默认找main当入口,还会自动链接标准库启动代码,要让它用_start,必须加参数:
gcc -nostdlib -static 你的汇编文件.s -o 输出文件
-nostdlib:关闭标准库和默认启动代码-static:静态链接,避免动态库依赖问题
不加这俩参数的话,gcc会忽略你的_start,继续找main,自然报找不到入口的错。
直接用ld链接的命令
针对x86_64架构,正确的ld命令是:
ld -m elf_x86_64 你的汇编文件.s -o 输出文件
32位x86架构的话把elf_x86_64换成elf_i386,确保架构和你的汇编代码匹配。
验证符号是否存在
用nm命令检查汇编编译出的目标文件:
nm 你的目标文件.o
如果输出里有T _start,说明符号是全局代码段的,没问题;如果是小写t,说明是局部符号,ld看不到,必须补.global _start。
排查编译器生成逻辑
- 确认你的编译器确实输出了
.global _start和_start:代码,有没有漏写全局声明,或者生成的汇编被截断? - 把编译器生成的汇编文件单独拿出来手动编译链接,看能不能成功,这样就能区分是编译器生成的汇编有问题,还是链接步骤的问题。
内容的提问来源于stack exchange,提问作者user18591665
相关产品推荐
相关产品推荐

