c/c++编译原理浅谈(三)

-------------前言

浑浑噩噩就看完了一遍《高级c/c++编译技术》,我知道看完一遍是不行,而且光是看也是不行的,先写下这篇博文也权当是记录下我的一些猜想,当然是未经过验证的,经过验证就不是猜想了。最终,在下有什么说得不对的,请各位大侠指正,不断学习不断进步!

-------------正文

先说一下这本书。这本书是由Milan Stevanovic大佬写的,卢誉声所译。结构内容是硬件基础,程序的生命周期,生命周期中的各个阶段的介绍,各类问题的解决。

上一篇中我们有说到,我们程序的执行起始点不是main函数的入口点,在它之前还有一些必要的东西需要执行,而且还挺复杂的。那么我们在执行文件时,它又是怎么一回事呢?

我们在开篇的时候有说过,程序的执行与物理硬件相关,我们要执行必须要真正地找到那个真实的地址,因为那个地址就真实地住着我们的数据和操作指令!那么问题来,我们的可执行文件的地址还不是真正的物理地址,这样他们是找不到那些数据和指令的。所以,在执行的前期有一个装载的过程。

装载器的作用

它的最重要的功能就是将链接器创建的节复制带进程内存映射中,它不需要了解各个节的内部结构,它只需要关心是否可读或可读写,以及在可执行问二建启动前是否需要打补丁。

加载过程

当识别出二进制格式以后,内核装载器模块就会派上用场。首先装载器会定位可执行二进制文件中的PT_INTERP段,用于动态加载过程(如果有的话)。

接着装载器会读取程序的二进制文件段的头,确定每个段的地址和字节长度。需要特别指出的是,在这个阶段装载器仍然不会向内存映射写入任何数据。装载器在此阶段至会建立并维护一组可执行文件段,也就是每个段的页宽,和程序内存映射关联的结构。

在程序启动之后,可执行文件复制段的操作才执行,分配给进程的物理内存页程序内存映射表之间的虚拟内存关系就已经建立好了。只有在当内核在运行时需要某一个程序段时才会开始加载其对应的页,这种策略使得程序中每一部分只有运行时真正需要时才会加载。

以上都是抄书上的,见谅哈,觉得也就是字面上的意思。

具体怎么做到以上的操作的,咱这就不讨论了。

哦,对了,还得提一下一个比较有趣的东西,那就是传参机制,调用函数我们已经涉及了,但是如何传参呢?当然,大佬们已经为了设计好了,就是基于栈的实现机制,比如说,cdecl,stdcall,fastcall,thiscall,每种惯例都是为不同设计视角的特定情况专门设计的,这里也不多讲了。

猜你喜欢

转载自blog.csdn.net/qq_38960899/article/details/79944199