Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 对主ld的未定义引用_C_Windows_Assembly_Ld - Fatal编程技术网

C 对主ld的未定义引用

C 对主ld的未定义引用,c,windows,assembly,ld,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 $ 我调用以生成

我正在尝试链接到文件-一个包含主函数的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
编辑2: 使用这些命令时,我获得了最佳效果:

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
文件链接成功,但在运行时,从未调用main。
也尝试使用coff格式,它也会链接,但Bochs会继续重新启动。

第一个错误是因为在C中,函数名为
\u name
,因此不能这样调用
main
,必须调用
\u main
。在TASM中,您可以设置调用约定,这样assmebler就可以自动调用正确的函数,我不知道nasm是否也有这样的功能

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


您是否尝试了
extern\u main,call\u main
?修复了第一个错误,内核中的第二个错误。c仍然存在我使用-r表示ld,只有当我链接kernel.o时,-r选项才起作用,因为kernel.o的格式似乎与elf32不同。在windows中,gcc是否可以创建一个elf格式的对象?您想做什么?您创建了一个*.bin文件,该文件看起来就像创建了一个独立的程序集模块。那你为什么需要一个精灵呢?谁会加载这个?我正在尝试创建一个引导加载程序-因为我不能保证c编译器不会更改函数和数据的顺序,所以我正在尝试预先编写一个调用函数main的小asm代码。