【问题标题】:Undefined reference to main ld对主 ld 的未定义引用
【发布时间】:2013-08-10 20:08:22
【问题描述】:

我正在尝试链接到文件 - 一个包含 main 函数的 c 文件和一个简单地跳转到 main 的 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

文件链接成功,但在运行时,主程序永远不会被调用。 也尝试使用 coff 格式,它也可以链接,但 Bochs 不断重启。

【问题讨论】:

  • 你试过extern _main, call _main吗?
  • 修复了第一个错误,kernel.c 中的第二个错误仍然存​​在

标签: c windows assembly ld


【解决方案1】:

第一个错误是因为在C中一个函数被命名为_name,所以你不能像这样调用main,你必须调用_main。在TASM中可以设置调用约定,所以汇编器会自动调用正确的函数,不知道nasm是否也有这样的功能。

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

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

【讨论】:

  • 我用 -r 表示 ld,它链接得很好
  • -r 选项仅在我链接 kernel.o 时才有效,因为 kernel.o 的格式似乎与 elf32 不同
  • 是否可以让gcc在windows中创建elf格式的对象?
  • 你想做什么?您创建一个 *.bin 文件,看起来好像您创建了一个独立的汇编模块。那么为什么你需要一个 ELF?谁来加载这个?
  • 我正在尝试创建一个引导加载程序 - 因为我不能保证 c 编译器不会更改函数和数据的顺序,所以我正在尝试添加一个小的 asm 代码来调用函数 main .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多