我回来了C/C++和ASM,我想玩一点点火。我发现,当您编译代码并将其链接到Windows的可执行文件时,它会动态链接到某些需要运行该应用程序的计算机上必须存在的库。您可以指定编译器不与它们链接,并为此创建自己的库。在C或程序集中制作一个简单的CRT0
除此之外(如果我在这里所说的一切都错了,请纠正我),这里有一个目标文件,它总是遵从我们应用程序的主代码并与其链接。它是crt0.o(C运行时)文件,据我所知,它准备堆栈,获取argc和argv并调用主函数(也可能是其他的东西)。我也相信这是系统在执行应用程序时调用的第一段代码。
所以,我想创建一个简单的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创建我的可执行文件,并让系统启动它。我知道互联网上有很多代码文件(C和ASM),但我想编写自己的代码文件以了解它是如何工作的。除了代码之外,我需要的是对它必须做什么以及如何编译/链接以实现它的一点帮助。 如果您知道任何有用的链接,也非常感激。
我的疑惑是:
如何编译/链接创建从我的代码的最后文件和C运行时?我是否必须从crt0.o调用主函数(使用extern指令)?当我执行g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe
时,出现“* undefined reference to __main *”错误。在crt0.o文件中定义了主函数吗?奇怪的是,如果我通过int start
更改int main
,我不会收到任何错误。那是什么意思?
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函数已经被创建(它们看起来像简单的构造函数和析构函数,我不知道)还有一个主函数,我不知道如何与.cpp main函数相关。我的意思是,我应该导入它吗?主函数和退出函数都会出现undefined reference
错误。
5.)必须c0具有特定的格式或包含特定的功能,以便系统找到它的开始?
好了,我没有看到它,使一个小信息crt0困难,使编译器将其连接到可执行文件,但也有一些事情我不能正确地看。我希望有人能够帮助我融合所有这些。由于
什么是您的实际目标这里? – 2013-02-23 16:46:06
C语言创建一个简单的信息crt0,链接它针对C++文件,使该文件只运行这一点。 – ali 2013-02-23 16:48:58
是的,但你比如希望能够做到'COUT <<“世界,你好!\ n”','叫兰特()',调用与静态存储时间'new' /'delete'或使用对象,等等等等?这些都是在启动时准备好的。 – 2013-02-23 16:51:06