MinGW Win32 + nasm:“未定义参考”

时间:2014-08-29 21:41:44

标签: gcc assembly mingw nasm undefined-reference

我目前正在开发一个用于学习目的的操作系统,直到现在它一直运行良好。然后我尝试从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,因此该错误与前导下划线无关!

2 个答案:

答案 0 :(得分:3)

在我的MinGW设置中,您需要在代码之前使用section指令。

; 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

答案 1 :(得分:2)

你遗漏了一些重要的东西,你的代码不在代码部分!

您的asm文件应如下所示:

test.asm

global _testfunc

section .text       ; <<<< This is important!!!        
; all code goes below this!                                                  
_testfunc:

    ret

test2.asm

extern _testfunc
global _testfunc2

section .text       ; <<<< Again, this is important!!!                                                          
_testfunc2:
    call    _testfunc
    ret