2011-04-21 66 views
8

我最近开始研究生成的代码使用C++运行时库的方式。在没有运行时库的情况下在Linux下编译C++

大部分我都很好奇,但我也想评估开发C++中的内核所需的最小内核所需的工作量。

所以我开始实现我自己的运行时库,但我有一个小问题。

int main(int argc, char **argv) 
{ 
    return 0; 
} 

用下面的命令编译此:

$克++ -ffreestanding -nostdlib -fno-内置-fno-RTTI -fno-例外-c main.cpp中

我得到这个警告:

/usr/bin/ld:warning:找不到条目符号_start;默认为00000000080480b8

然后,当我尝试执行产生的二进制文件时,出现“分段错误”。 我试图编译“main.cpp”和一个ASM文件。

[global _start] 
[extern main] 

_start: 
    call main 

链接对象的文件以“LD”手动,我没有报警,但二进制还是养中“segmentation fault”。

我想我错过了一些东西。例如,在系统C库在“__libc_start_main”中执行“main”调用之前和之后,可能需要执行某些操作。此外,如果有人对我应阅读的有关该主题的网站,文档或书籍有任何建议,我将非常感激。

感谢,

帕特里克

+5

[如何构建最简单的Unix可执行文件](http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html) – QuantumMechanic 2011-04-21 00:51:19

+0

仅供参考,'_start'在CRT中。 – 2011-04-21 00:54:15

回答

5

好了,感谢QuantumMechanic的链接我设法找到了问题: http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html

我只是忘了我的基础知识在linux编程,更重要的是如何结束的程序进行处理。

基本上,我需要生成系统调用中断“exit”来处理程序的结束。

[BITS 32] 

[global _start] 
[extern main] 

_start: 
    call main 
    mov ebx, eax ; Move the returned value in the register used as argument of exit() 
    mov eax, 1 ; Indicates the id of the syscall to execute 
    int 0x80  ; Triggers the syscall interrupt 

所以现在我可以使用我自己的RTL编译任何C++程序来进行一些测试。

请注意,如果永远不会到达“main”函数的末尾,它在内核中将不再需要。

谢谢!

1

如果你愿意使用gcc的一个小(200K)部分安装,可以在libgcc_s链接。这将为您提供您的程序执行静态初始化所需的所有代码,并致电main

1

当你构建一个内核时,你必须考虑它是如何启动的。通常这是引导加载程序的责任,并且它们远非标准。这肯定不像启动Linux应用程序。因此,当你打算忽略这种启动方式时,不必太担心_start

相关问题