Linux x64下链接C主函数与GAS汇编函数时遇_start入口符号缺失问题
Linux x64下C调用GAS汇编函数的链接问题解决
问题描述
本人能读懂汇编代码,正在学习编写小型汇编函数,但在Linux x64平台下,无法完成调用外部GAS汇编函数的C主程序的链接操作。相关代码与编译命令如下:
main.c代码
#include <stdio.h> extern int somefunc(); int main() { int x = somefunc(); printf("returned %d\n", x); return 0; }
sf.s汇编代码
.global somefunc .data .text somefunc: movl $123, %eax ret
编译命令及错误提示
gcc -c -fno-pie main.c -o main.o as sf.s -o sf.o ld -lc main.o sf.o -o m
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401020
解决方案
直接用ld链接C程序会缺失C运行时的启动代码,导致找不到_start入口符号。正确的做法是用gcc来完成链接操作,它会自动处理C运行时的依赖:
正确的编译链接步骤
- 编译C源文件为目标文件:
gcc -c -fno-pie main.c -o main.o - 汇编汇编源文件为目标文件:
as sf.s -o sf.o - 用gcc链接生成可执行文件:
gcc main.o sf.o -o m
原理说明
gcc在链接时会自动包含C运行时的启动对象文件(如crt1.o、crti.o等),这些文件提供了程序的入口点_start,负责初始化C运行环境、调用main函数并处理程序退出逻辑。而直接用ld -lc仅链接了libc库,但没有包含这些启动代码,因此会出现找不到_start的错误。
另外,你的汇编代码符合x64调用约定:int类型的返回值存储在rax寄存器中,movl $123, %eax会将32位值零扩展到64位的rax,满足调用要求。
内容的提问来源于stack exchange,提问作者Jason Nordwick
相关产品推荐
相关产品推荐

