繁体   English   中英

从ASM调用的C ++代码中的标准库的链接

[英]Linkage of standard libraries in C++ code called from ASM

当我开发“ OsDev”项目时,我正在学习一个新的东西(对于那些由于Web开发很长时间没有用C / C ++编写代码的人来说,这有点“新”)。 我在另一个线程中发现,从ASM调用C ++函数需要有一个extern "C"前缀,但是现在我对标准库的内衬(例如cstdio等)有疑问。我坚持此消息。

kc.o: In function `kmain':
kernel.cpp:(.text+0x3e4): undefined reference to `strlen`

C ++

#include <string.h>
#include <cstdio>

#include "inc/screen.h"

extern "C" void kmain()
{
    clearScreen();
    kernel_print((char*)"Hello Github! :-)", 0x04);
}

如果我尝试使用strlen() ,它将不会链接。 (顺便说一句,包括screen.h由于某种原因在工作)。 编译脚本

nasm -f elf32 kernel.asm -o kasm.o
g++ -c kernel.cpp -o kc.o -lgcc -m32  -Wall -Wextra -O2
ld -m elf_i386 -T link.ld -o kernel.bin kasm.o kc.o

链接

OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
SECTIONS
 {
   . = 0x100000;
   .text : { *(.text) }
   .data : { *(.data) }
   .bss  : { *(.bss)  }
 }

感谢您的任何建议。 :)

您的代码无法工作,因为内核无法直接使用共享库。

为什么我不能直接在内核中使用共享库?

当操作系统加载应用程序时,所有必需的文件都被带入其地址空间。 这包括可执行文件和任何动态库(所有符合ABI的ELF应用程序将始终与系统库-C标准库或libc链接 )。

但是在加载内核时,仅加载原始可执行文件。 Multiboot 2(使用GRUB bootloader)将允许您加载可以是动态库的内核模块 但是,内核仍然必须知道如何链接自身和物理内存中的内核模块。 为此,您必须在内核中实现ELF解析器和动态链接器。

在实施内核之前,请确保您的内核足够成熟,可以系统地处理动态内存分配,分页和其他基本功能。

如何使用libc的功能?

通常,您不会使用libc的所有用户空间功能。 但是像memcpystrlenstrcpyn类的东西是绝对必要的。 您将必须自己实现这些功能,但是更好的是,您可以更改这些功能的名称。 例如,如果您更喜欢使用camelCase作为函数名,那么还可以使用函数名,例如copyMemorylengthOfString等。

https://github.com/SukantPal/Silcos-Kernel

我已经构建了自己的内核,该内核在KernelHost / Source / Util / CircuitPrimitive.cpp中具有所需功能的一些实现。 您可以调查一下。 此外,它还具有完整的模块链接器。 (KernelHost,ModuleFramework等。这些父文件夹包含单独的内核模块源代码)。

到目前为止,请确保不要在内核中使用标准的C标头。 自行实现所有必需的功能,包括printf

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM