【问题标题】:Compiling C++ under Linux without the runtime library在没有运行库的情况下在 Linux 下编译 C++
【发布时间】:2011-08-09 22:36:36
【问题描述】:

我最近开始探索生成代码使用 C++ 运行时库的方式。

主要是我很好奇,但我也想评估开发在 C++ 中启动内核所需的最少内容所需的工作量。

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

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

使用以下命令编译:

$ g++ -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions -c main.cpp

我收到此警告:

/usr/bin/ld:警告:找不到入口符号_start;默认为 00000000080480b8

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

[global _start]
[extern main]

_start:
  call main

使用“ld”手动链接目标文件,我没有收到警告,但二进制文件仍在引发“分段错误”。

我想我错过了什么。可能在调用“main”之前和之后必须做一些事情,就像系统 C 库在“__libc_start_main”中所做的那样。

另外,如果有人对我应该阅读的有关该主题的网站、文档或书籍有任何推荐,我将不胜感激。

谢谢,

帕特里克

【问题讨论】:

标签: c++ g++ runtime main


【解决方案1】:

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

我只是忘记了我的linux编程基础,更重要的是如何处理程序结束。

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

[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 在 linux 上编译任何 C++ 程序来进行一些测试。

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

谢谢!

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      当您构建内核时,您必须考虑它是如何启动的。通常这是引导加载程序的责任,它们远非标准。这肯定不同于启动 Linux 应用程序。因此,当您无论如何都要忽略这种开始方式时,过多担心_start 是不明智的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-08-18
        • 1970-01-01
        • 1970-01-01
        • 2020-03-25
        • 1970-01-01
        • 2021-03-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多