什么原因导致“x.asm:(.text+0xd): undefined reference to ‘y’"? [英] What causes "x.asm:(.text+0xd): undefined reference to `y'"?

查看:53
本文介绍了什么原因导致“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 in boot.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 assemble boot.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 to final.bin with LD, you can convert final.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 is 0x1badb002 not 0xbad. Since you haven't specified a video configuration in your Multiboot header FLAGS 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆