汇编与C语言链接报错:undefined reference to `asm_main()'
链接C与汇编代码时的未定义引用及架构兼容问题排查
问题概述
尝试将C驱动文件、主汇编文件、辅助汇编(asm_io)链接为可执行文件,所有目标文件生成成功,但链接阶段出现undefined reference to 'asm_main()'错误。后续改用Win32格式编译汇编文件后,又出现架构不兼容及大量标准库函数未定义的错误。
相关代码与命令
C驱动文件(driver.c)
#include "cdecl.h" int PRE_CDECL asm_main( void ) POST_CDECL; int main() { int ret_status; ret_status = asm_main(); return ret_status ; }
主汇编文件(first.asm)关键片段
%include "asm_io.inc" segment .data prompt1 db "Enter a number: ", 0 prompt2 db "Enter another number: ", 0 outmsg1 db "You entered ", 0 outmsg2 db " and ", 0 outmsg3 db ", the sum of these is ", 0 segment .bss input1 resd 1 input2 resd 1 segment .text global _asm_main _asm_main: enter 0,0 pusha ; 输入输出逻辑(省略中间代码) popa mov eax, 0 leave ret
初始编译与链接命令
# 编译C文件 i586-pc-msdosdjgpp-gcc.exe -c driver.c # 编译汇编文件 nasm -f coff first.asm nasm -f coff asm_io.asm # 链接 i586-pc-msdosdjgpp-gcc.exe -o first driver.o first.o asm_io.o
错误信息:undefined reference to 'asm_main()'
后续尝试的命令
# 改用Win32格式编译汇编 nasm -f win32 first.asm nasm -f win32 -d COFF_TYPE asm_io.asm # 链接 gcc driver.o first.obj asm_io.obj -o first.exe
错误信息:
6 architecture of input file `asm_io.obj' is incompatible with i386:x86-64 output driver.o:driver.c:(.text+0xe): undefined reference to `asm_main' asm_io.obj:asm_io.asm:(.text+0x10): undefined reference to `_scanf' ...(大量标准库函数未定义)
问题根源与修复步骤
1. 符号名不匹配(核心问题)
C驱动文件中声明的函数是asm_main,但汇编文件导出的符号是_asm_main,导致链接器无法匹配符号。
修复方案二选一:
- 修改汇编文件:将
global _asm_main改为global asm_main,将_asm_main:改为asm_main: - 修改C文件:将函数声明改为
int PRE_CDECL _asm_main( void ) POST_CDECL;,调用处改为ret_status = _asm_main();
2. 目标文件格式不兼容
DJGPP环境使用DOS平台的COFF格式,与Windows的Win32 COFF格式不兼容。后续尝试的nasm -f win32生成的目标文件无法被DJGPP的GCC链接,且普通gcc默认编译64位程序,与32位目标文件冲突。
修复方案:统一使用DJGPP兼容的编译命令,清理旧目标文件后重新编译:
# 清理旧文件 rm -f driver.o first.o asm_io.o first.exe first.obj asm_io.obj # 重新编译 i586-pc-msdosdjgpp-gcc.exe -c driver.c nasm -f coff first.asm nasm -f coff asm_io.asm # 链接生成可执行文件 i586-pc-msdosdjgpp-gcc.exe -o first.exe driver.o first.o asm_io.o
3. 标准库依赖问题
asm_io.asm中调用了scanf、printf等C标准库函数,必须使用DJGPP的GCC链接(默认自动链接标准库),不能用普通Windows的GCC链接。
额外检查
- 确保
cdecl.h、asm_io.inc文件在当前工作目录下,或编译时通过-I参数指定头文件路径 - 确认汇编文件编译时无语法错误,
asm_io.asm依赖的asm_io.inc必须存在
内容的提问来源于stack exchange,提问作者B.Doe
相关产品推荐
相关产品推荐

