Gcc MinGW-Win32+;nasm:“;“未定义引用”;
我目前正在开发一个用于学习的操作系统,到目前为止,它一直运行良好。然后,我试图从C代码调用一个汇编函数,该函数是用Gcc MinGW-Win32+;nasm:“;“未定义引用”;,gcc,assembly,mingw,nasm,undefined-reference,Gcc,Assembly,Mingw,Nasm,Undefined Reference,我目前正在开发一个用于学习的操作系统,到目前为止,它一直运行良好。然后,我试图从C代码调用一个汇编函数,该函数是用nasm,-fwin32编译的,但我得到的只是一个“未定义的引用”错误。我在pure assembler中创建了一个小示例,它也有同样的问题,但很容易理解,而且小得多: 它包括两个文件: 测试。asm: [bits 32] global _testfunc _testfunc: ret test2.asm: [bits 32] extern _testfunc globa
nasm,-fwin32
编译的,但我得到的只是一个“未定义的引用”错误。我在pure assembler中创建了一个小示例,它也有同样的问题,但很容易理解,而且小得多:
它包括两个文件:
测试。asm:
[bits 32]
global _testfunc
_testfunc:
ret
test2.asm:
[bits 32]
extern _testfunc
global _testfunc2
_testfunc2:
call _testfunc
ret
extern void testfunc(void);
void start()
{
testfunc();
}
这是我的编译器/链接器脚本(使用windows批处理文件):
这将导致以下错误:
test2.o:test2.asm:(.text+0x1): undefined reference to `testfunc'
为了扩展问题,从C调用函数时也会发生同样的情况:
test.c:
[bits 32]
global _testfunc
_testfunc:
ret
test2.asm:
[bits 32]
extern _testfunc
global _testfunc2
_testfunc2:
call _testfunc
ret
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中,它总是说
\u testfunc
,因此错误与前导下划线无关 您遗漏了一些重要内容,您的代码不在代码部分
您的asm文件应如下所示:
test.asm
global _testfunc
section .text ; <<<< This is important!!!
; all code goes below this!
_testfunc:
ret
extern _testfunc
global _testfunc2
section .text ; <<<< Again, this is important!!!
_testfunc2:
call _testfunc
ret
在my MinGW设置中,在代码之前需要一个
部分
指令
; foo.asm
[bits 32]
global _testfunc
section .text
_testfunc:
ret
然后汇编为win32格式:
nasm -fwin32 foo.asm -o foo.o
现在您可以检查testfunc
是否存在:
$ nm foo.o
00000000 a .absolut
00000000 t .text
00000001 a @feat.00
00000000 T _testfunc
T
表示文本部分是全局的,所以我们可以开始了
注意,我避免命名任何test
,因为这是一个shell命令。这会导致无尽的悲伤
C函数如您所示,但将文件命名为其他名称:
// main.c
extern void testfunc(void);
int main(void)
{
testfunc();
return 0;
}
然后,为了构建一个可执行文件,让gcc
来完成这项繁重的工作,因为ld
有时需要神秘的参数
gcc -ffreestanding main.c foo.o -o main
你在C语言中的问题很明显:
externvoidtestfunc(void)
不过是对编译器的一个承诺,即testfunc
是在其他地方定义的。如果在编译过程中,无法找到您承诺的定义的testfunc
,则会出现问题错误。testfunc
在哪里定义?至于nasm,我怀疑同样的情况也在发生,但是我没有写足够的asm来知道。谢谢你的回答,但是testfunc不是在test.o中定义的吗?这就是全局函数所做的,不是吗?不。我看到的只是test.c
——这里只有一个外部声明—没有存储分配给testfunc
,也没有定义。你有另一个C文件吗?test2.c在什么地方?我不知道你在test.asm中的定义是否足够。看,你不需要asm文件中的[global\u testfunc]
和[global\u testfunc2]
吗?如果你再次阅读asm文件,你会看到它们确实包含全局声明。