加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 在C或汇编中制作一个简单的CRT0

发布时间:2020-12-16 07:03:32 所属栏目:百科 来源:网络整理
导读:我带着C/C++和ASM回来了,我想用火来玩一点.我发现当您编译代码并将其链接到 Windows的可执行文件时,它会动态链接到某些必须存在于该应用程序运行的计算机上的库.您可以指定编译器不链接它们并为此创建自己的库. 除此之外(如果我在这里所说的一切都错了,请纠
我带着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创建我的可执行文件,并让系统启动它.我知道互联网上有很多代码文件(C和ASM),但我想自己编写,以了解它是如何工作的.不仅仅是代码我需要的是一些帮助,它必须做什么以及如何编译/链接以实现它.
如果您知道任何有用的链接,也非常感谢.

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

// crt0.c
__asm(".section .textn" 
".global _startn"
"_start:n"
"mov $0,%ebpn"
"push %ebpn"
"mov %esp,%ebpn"
"push %esin"
"push %edin"
"call _initn"
"pop %edin"
"pop %esin"
"call mainn"
"movl %eax,%edin"
"call exitn"
".section .initn"
".global _initn"
"_init:n"
"push %ebpn"
"mov %esp,%ebpn"
".section .finin"
".global _finin"
"_fini:n"
"push %ebpn"
"mov %esp,%ebpn");

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

好吧,我觉得制作一个小的crt0并让编译器将它附加到可执行文件上并不困难,但是有一些我无法正确看到的东西.我希望有人能帮我把这一切都融合在一起.谢谢

解决方法

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

#// crt0.c
__asm(".section .textn" 
".global _startn"
"_start:n"
"mov $0,%ebpn"
"call mainn"
"pop  %ebpn"
"retn");

编辑:空__main:

__asm(".global __mainn"
      "__main:n" 
      "retn");

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读