什么原因导致“x.asm:(.text+0xd): undefined reference to ‘y’"? [英] What causes "x.asm:(.text+0xd): undefined reference to `y'"?
问题描述
很长一段时间我都没有使用 C 和汇编程序进行编程(大约 2 年).现在我决定重新开始,但我想做一些更复杂的事情.我想过创建一个简单的内核.现在我在互联网上找到了这个源代码:
boot.asm:
全局加载器外部内核_mainMAGIC equ 0xbad标志等于 0x3校验和等式 -(MAGIC+FLAGS)节.text对齐 4dd魔法dd 标志dd 校验和装载机:调用 kernel_main命令行放弃:高退出
内核.c:
void print(char *text) {字符*内存=(字符*)0xb8000;而(*文本){*内存++ = *文本++;*内存++ = 0x3;}}无效内核主(){print("我的猫有时闻起来像咖啡馆.我喜欢它.");}
linker.ld:
ENTRY(加载器)部分{.= 0x100000;.text : { *(.text) }}
注意:我用GCC"编译了 C 文件,用NASM"编译了汇编文件.
如果我尝试这个命令:
ld -T linker.ld -elf_i386 -o final.bin boot.o kernel.o
它说:boot.asm:(.text+0xd): undefined reference to `kernel_main'".我怎样才能解决这个问题?我在 Windows 上工作,不想在 Linux 或任何东西上运行 VM.提前致谢!
这是我的 GCC 命令:
gcc -m32 -o kernel.o srckernel.c -nostdlib -nostartfiles -nodefaultlibs
这是我的 NASM 命令:
nasm -f elf32 -o boot.o boot.asm
有很多问题.鉴于错误,我将假设:
<块引用>boot.asm:(.text+0xd): 对 kernel_main
您没有使用 ELF 交叉编译器,并且您使用的是生成本机 Windows 可执行文件(即 Cygwin 和 MinGW)的 GCC 编译器.我强烈建议使用 i686(或 x86_64)
<小时>脚注:
- 1生成 Win64 PE32+ 对象时,函数名称上的额外下划线不适用.
For a long time I had not programmed with C and Assembler (about 2 years). Now I have decided to start again but I would like to do something much more complicated. I thought about creating a simple kernel. Now I found this source code on the internet:
boot.asm:
global loader
extern kernel_main
MAGIC equ 0xbad
FLAGS equ 0x3
CHECKSUM equ -(MAGIC+FLAGS)
section .text
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
loader:
call kernel_main
cli
quit:
hlt
jmp quit
kernel.c:
void print(char *text) {
char *memory = (char*)0xb8000;
while(*text) {
*memory++ = *text++;
*memory++ = 0x3;
}
}
void kernel_main() {
print("My cat sometimes smells like cafe. I love it.");
}
linker.ld:
ENTRY(loader)
SECTIONS {
. = 0x100000;
.text : { *(.text) }
}
Note: I compiled the C file with "GCC" and the Assembler file with "NASM".
If I try this command:
ld -T linker.ld -elf_i386 -o final.bin boot.o kernel.o
It says: "boot.asm:(.text+0xd): undefined reference to `kernel_main'". How can I fix this? Im working on windows and do not want to run a VM with Linux or anything. Thanks in advance!
Edit: This is my GCC command:
gcc -m32 -o kernel.o srckernel.c -nostdlib -nostartfiles -nodefaultlibs
This is my NASM command:
nasm -f elf32 -o boot.o boot.asm
There are a number of things wrong. I will assume given the error:
boot.asm:(.text+0xd): undefined reference to
kernel_main
that you are not using an ELF cross compiler and that you are using a GCC compiler that generates native Windows executables (ie. Cygwin and MinGW). I highly recommend the use of an i686 (or x86_64) ELF cross compiler for OS Development especially on Windows.
Your primary problems are:
The option
-elf_i386
was probably meant to be-melf_i386
however that is even incorrect. With a GCC that targets windows you will want to use-mi386pe
to output as Win32 PE/COFF format. The Windows GCC linker usually doesn't know how to generate ELF executables. I also recommend using the-N
option when using LD to output i386pe format. Change your linker command to be:ld -N -T linker.ld -mi386pe -o final.bin boot.o kernel.o
With Win32 PE/COFF objects1: functions that use the CDECL calling convention have to have an underscore (
_
) prepended to them.kernel_main
needs to be_kernel_main
. You need to change these lines inboot.asm
from:extern kernel_main call kernel_main
to:
extern _kernel_main call _kernel_main
You don't show how you compile
kernel.c
and how you assembleboot.asm
but they should look similar to:nasm -f win32 boot.asm -o boot.o gcc -g -c -m32 -ffreestanding kernel.c -o kernel.o
When you do manage to generate
final.bin
it is a Windows PE executable. The Multiboot specification requires ELF executables. After linking tofinal.bin
with LD, you can convertfinal.bin
to ELF format with:objcopy -O elf32-i386 final.bin final.elf
final.elf
should now be usable as a Multiboot ELF executable.There is an issue with your Multiboot header in
boot.asm
. The Multiboot magic value is0x1badb002
not0xbad
. Since you haven't specified a video configuration in your Multiboot headerFLAGS
should not have Bit 1 set,FLAGS
should be 0x1 instead of 0x3. Change your Multiboot header from:MAGIC equ 0xbad FLAGS equ 0x3
to:
MAGIC equ 0x1badb002 FLAGS equ 0x1
With the changes noted above I was able to generate an ELF executable called final.elf
. When run with QEMU using the command:
qemu-system-i386 -kernel final.elf
The output I get is:
Footnotes:
- 1The extra underscore on function names doesn't apply when generating Win64 PE32+ objects.
这篇关于什么原因导致“x.asm:(.text+0xd): undefined reference to ‘y’"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!