用C或汇编语言制作一个简单的CRT0 [英] Make a simple CRT0 in C or assembly

查看:217
本文介绍了用C或汇编语言制作一个简单的CRT0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm back with C/C++ and ASM and I want to play a little bit with fire. I found out that when you compile and link code into an executable for Windows it is dynamically linked to some libraries that must exists on any computer where that application is expected to run. You can specify the compiler to not link against them and create your own libraries for that.

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

Apart from that (and please, correct me if I'm wrong in everything I say here) there's an object file that is always complied and linked along the main code of our app. It is the crt0.o (the C runtime) file and, as I know, it prepares the stack, get argc and argv and call the main function (and maybe other things). I also believe it is the first piece of code called by the system when executing the application.

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

So, I am trying to create a simple crt0.obj and link it against a simple C++ object file

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

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

I use GCC and I want to make use of no standard library, so my command looks like:

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

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

I suppose that the -nostartfiles directive is what tells the linker to not embed the default crt0.o, so it expects me to give every definition for any function and handle the start-up of the application. I am a little confused here.

无论如何,我想创建一个非常基本的crt0对象文件,这足以使GCC创建我的可执行文件,并足以使系统启动它.我知道Internet上有很多代码文件(C和ASM),但是我想编写自己的代码文件以了解其工作原理.除了编写代码外,我还需要一些帮助,以了解必须执行的操作以及如何进行编译/链接以实现此目的. 如果您知道任何有用的链接,也将不胜感激.

Anyway, I want to create a very basic crt0 object file, that will be enough for GCC to create my executable, and for the system to start it. I know there are many code files (C and ASM) on the Internet but I want to write my own in order to learn how it works. More than code what I need is a little help on what must it do and how to compile/link in order to achieve it. If you know any helpful link that is also very appreciated.

我的疑问是:
1..编译器/链接如何通过我的代码和C运行时创建最终文件?我是否必须从crt0.o调用main函数(使用extern指令)?当我执行g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe时,出现"*对__main *的未定义引用"错误.主要功能是否在crt0.o文件中定义?奇怪的是,如果我将int main更改为int start,我不会得到任何错误.这是什么意思?
2..crt0必须包含哪些基本操作(例如获取命令行参数,调用main)?
3..我的代码文件是CPP,而crt0是C文件(与GCC一起编译)内的一部分程序集.我将发布一些我发现并部分理解的片段成功创建的"frankencode":

My doubts are:
1. How does the compiler/link create the final file from my code and the C runtime? Do I have to call the main function from crt0.o (using an extern directive)? When I execute g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe I get "*undefined reference to __main*" error. Is the main function defined in the crt0.o file? It's strange that if I change int main by int start I don't get any error. What does that mean?
2. Which are the essential operations that a crt0 must contain (like getting command-line arguments, calling main)?
3. My code file is CPP and the crt0 is a piece of assembly inside a C file (compiled with GCC). I will post some "frankencode" I managed to create from pieces I found and partially understood:

// 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是否必须具有特定格式或包含特定功能,以便系统找到其起始位置?

4.) So, in this file, I made some calls to initialization functions. The init and fini functions are already created (they look like simple constructors and destructors, I don't know) There's also the main function, which I don't know how is related to the .cpp main function. I mean, am I supposed to import it? I get undefined reference errors for both main and exit functions.
5.) Must the c0 have a specific format or contain a specific function so the system find its start?

嗯,我不认为很难创建一个小的crt0并使编译器将其附加到可执行文件上,但是有些事情我看不到.我希望有人可以帮助我将所有这些都整合在一起.谢谢

Well, I don't see it difficult to make a small crt0 and make the compiler attach it to the executable, but there are some things I am not able to see correctly. I hope somebody can help me fit all this together. Thanks

推荐答案

我没有要测试的Windows计算机,但这应该是您需要的基本信息:

I don't have a windows machine to test on, but this should be the basic bits you need:

#// 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");

这篇关于用C或汇编语言制作一个简单的CRT0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆