5

我用 C/C++ 和 ASM 回来了,我想玩一点火。我发现,当您将代码编译并链接到 Windows 的可执行文件中时,它会动态链接到一些库,这些库必须存在于预期运行该应用程序的任何计算机上。您可以指定编译器不链接它们并为此创建自己的库。

除此之外(如果我在这里所说的一切都错了,请纠正我)还有一个目标文件,它总是沿着我们应用程序的主代码编译和链接。它是 crt0.o(C 运行时)文件,据我所知,它准备堆栈、获取 argc 和 argv 并调用 main 函数(可能还有其他东西)。我也相信它是系统在执行应用程序时调用的第一段代码。

所以,我正在尝试创建一个简单的 crt0.obj 并将其链接到一个简单的 C++ 目标文件

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

我使用 GCC 并且我不想使用标准库,所以我的命令如下所示:

g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe crt0.o

我想-nostartfiles指令告诉链接器不要嵌入默认的 crt0.o,因此它希望我为任何函数提供每个定义并处理应用程序的启动。我在这里有点困惑。

无论如何,我想创建一个非常基本的 crt0 目标文件,这足以让 GCC 创建我的可执行文件,并让系统启动它。我知道 Internet 上有很多代码文件(C 和 ASM),但我想编写自己的代码文件以了解它是如何工作的。我需要的不仅仅是代码,而是关于它必须做什么以及如何编译/链接以实现它的一点帮助。如果您知道任何有用的链接,也非常感谢。

我的疑问是:
1.编译器/链接如何从我的代码和 C 运行时创建最终文件?我是否必须从 crt0.o 调用 main 函数(使用 extern 指令)?当我执行时,g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe我得到“* undefined reference to __main*”错误。在crt0.o文件中定义了main函数吗?奇怪的是,如果我改变int mainint start没有得到任何错误。这意味着什么?
2. crt0 必须包含哪些基本操作(如获取命令行参数、调用 main)?
3.我的代码文件是 CPP,crt0 是 C 文件中的一个程序集(用 GCC 编译)。我将发布一些我设法从我发现并部分理解的片段中创建的“frankencode”:

// crt0.c
__asm(".section .text\n" 
".global _start\n"
"_start:\n"
"mov $0, %ebp\n"
"push %ebp\n"
"mov %esp, %ebp\n"
"push %esi\n"
"push %edi\n"
"call _init\n"
"pop %edi\n"
"pop %esi\n"
"call main\n"
"movl %eax, %edi\n"
"call exit\n"
".section .init\n"
".global _init\n"
"_init:\n"
"push %ebp\n"
"mov %esp, %ebp\n"
".section .fini\n"
".global _fini\n"
"_fini:\n"
"push %ebp\n"
"mov %esp, %ebp\n");

4.)所以,在这个文件中,我调用了一些初始化函数。init 和 fini 函数已经创建(它们看起来像简单的构造函数和析构函数,我不知道)还有 main 函数,我不知道它与 .cpp main 函数有什么关系。我的意思是,我应该导入它吗?主函数和退出函数都undefined reference出现错误。
5.) c0 必须具有特定格式或包含特定功能,以便系统找到它的开始吗?

好吧,我认为制作一个小的 crt0 并使编译器将其附加到可执行文件并不难,但是有些事情我无法正确看到。我希望有人可以帮助我将所有这些组合在一起。谢谢

4

1 回答 1

1

我没有要测试的 Windows 机器,但这应该是您需要的基本位:

#// crt0.c
__asm(".section .text\n" 
".global _start\n"
"_start:\n"
"mov $0, %ebp\n"
"push %ebp\n"
"mov %esp, %ebp\n"
"call main\n"
"pop  %ebp\n"
"ret\n");

编辑:空__main

__asm(".global __main\n"
      "__main:\n" 
      "ret\n");
于 2013-02-23T16:59:04.893 回答