对主ld的未定义引用

时间:2013-08-10 20:08:23

标签: c windows assembly ld

我正在尝试链接到文件 - 包含主要功能的c文件和只是跳转到主文件的asm文件。

我安装了mingw。 我的档案:

//kernel.c
void some_function(){
}
void main(){
char* video_memory = (char*) 0xb8000;
*video_memory = 'X';
some_function();
}

;kernel_entry.asm
[bits 32]
[extern main]
call main
jmp $

我调用构建的命令:

gcc -ffreestanding -c kernel.c -o kernel.o
nasm kernel_entry.asm -f elf -o kernel_entry.o
ld -o kernel.bin -Ttext 0x1000 kernel_entry.o kernel.o

我得到的错误:

kernel_entry.o:(.text+0x1): undefined reference to `main'
kernel.o:kernel.c:(.text+0xf): undefined reference to `__main'

编辑:

哪些命令有效:

ld -r -o kernel.out -Ttext 0x1000 kernel.o
objcopy -O binary -j .text kernel.out kernel.bin

当我尝试使用-r运行ld时出现错误:

ld: Relocatable linking with relocations from format elf32-i386 (kernel_entry.o)
 to format pe-i386 (kernel.bin) is not supported

EDIT2: 使用这些命令时,我得到了最好的结果:

gcc -ffreestanding -c kernel.c -o kernel.o
nasm kernel_entry.asm -f win32 -o kernel_entry.o
ld -r -o kernel.out -Ttext 0x1000 kernel_entry.o kernel.o
objcopy -O binary -j .text kernel.out kernel.bin

文件成功链接,但在运行时,主要永远不会被调用。 也尝试使用coff格式,它也链接,但Bochs一直在重新启动。

1 个答案:

答案 0 :(得分:1)

第一个错误是因为在C中,函数名为_name,因此您无法调用main,因此必须调用_main。在TASM中你可以设置调用约定,因此assmebler可以自动调用正确的函数,我不知道nasm是否还有这样的特性。

第二个问题可能是,因为您直接调用链接器。在这种情况下,您必须指定C启动模块,该模块通常由编译器添加到链接器选项。通常我认为这是一个名为crt0的文件。如果您编写自己的启动代码,则必须自己提供。此模块从OS特定入口点为C设置环境。我想你的项目中缺少这个。

http://en.wikipedia.org/wiki/Crt0