【发布时间】:2014-10-23 23:02:44
【问题描述】:
我目前正在开发一个用于学习目的的操作系统,到目前为止它运行良好。然后我尝试从 C 代码调用一个用nasm, -fwin32 编译的汇编程序函数,但我得到的只是一个“未定义的引用”错误。我在纯汇编程序中创建了一个小例子,它有同样的问题,但很容易理解并且更小:
它包括两个文件:
test.asm:
[bits 32]
global _testfunc
_testfunc:
ret
test2.asm:
[bits 32]
extern _testfunc
global _testfunc2
_testfunc2:
call _testfunc
ret
这是我的编译器/链接器脚本(使用 Windows 批处理文件):
nasm.exe -f win32 test.asm -o test.o
nasm.exe -f win32 test2.asm -o test2.o
ld test.o test2.o -o output.tmp
这会导致错误:
test2.o:test2.asm:(.text+0x1): undefined reference to `testfunc'
为了扩展这个问题,从 C 调用函数时也会发生同样的情况:
test.c:
extern void testfunc(void);
void start()
{
testfunc();
}
使用此链接器脚本:
gcc -ffreestanding -c test.c -o testc.o
nasm.exe -f win32 test.asm -o test.o
ld test.o testc.o -o output.tmp
在test.o、test2.o和testc.o中,总是说_testfunc,所以错误与前导下划线无关!
【问题讨论】:
-
您在 C 中的问题很明显:
extern void testfunc(void);只不过是向编译器承诺testfunc在其他地方定义。如果在编译期间,testfunc无法按照您的承诺定义,您将收到相关错误。testfunc在哪里定义?至于 nasm,我怀疑同样的情况正在发生,但我没有写足够的 asm 来知道。 -
感谢您的回答,但 testfunc 不是在 test.o 中定义的吗?这就是全局所做的,不是吗?
-
没有。我所看到的只是
test.c——而你所拥有的只是一个外部声明——没有为testfunc分配存储空间,也没有definition。你有另一个C文件吗? test2.c 某处?不知道你在 test.asm 中定义是否够用。 -
看,你在 asm 文件中不需要
[global _testfunc]和[global _testfunc2]吗? -
如果您再次阅读 asm 文件,您会发现它们确实包含全局声明。
标签: gcc assembly mingw nasm undefined-reference