2013-02-23 62 views
4

我回来了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困难,使编译器将其连接到可执行文件,但也有一些事情我不能正确地看。我希望有人能够帮助我融合所有这些。由于

+0

什么是您的实际目标这里? – 2013-02-23 16:46:06

+0

C语言创建一个简单的信息crt0,链接它针对C++文件,使该文件只运行这一点。 – ali 2013-02-23 16:48:58

+1

是的,但你比如希望能够做到'COUT <<“世界,你好!\ n”','叫兰特()',调用与静态存储时间'new' /'delete'或使用对象,等等等等?这些都是在启动时准备好的。 – 2013-02-23 16:51:06

回答

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"); 
+0

是的,但我得到“未定义参考到__main”当我编译包含的主要功能的CPP。所以,我不知道如何让编译器知道从哪里找到我从这段代码中调用的main。 – ali 2013-02-23 17:05:20

+0

如果你反汇编你的'main.o',是否有任何机会调用'__main'?我认为MingW会这样称呼一些构造函数和这些东西。在这种情况下,你必须添加我在上面编辑过的代码[注释中的代码转到...] – 2013-02-23 17:10:14

相关问题