《程序员自我修养》阅读笔记-可执行文件装载与进程

1 装载方式:页映射。操作系统将物理内存划分成页(比如每个页大小16K),可执行文件也按照页划分。每次需要哪个页时就将其装载到物理内存中某个空闲页。若没有空闲页,可以采取一定策略将物理内存中某个页换出。

2 可执行文件装载的过程。

(1)创建虚拟地址空间。分配页目录。这一步是建立虚拟空间到物理空间的映射关系。

(2)读取可执行文件头,建立虚拟空间与可执行文件的映射关系。这个映射关系的作用是以后发生页错误的时候,操作系统能够从这个映射关系中知道缺页在可执行文件中的位置。

(3)将cpu的指令寄存器设置成可执行文件的入口,开始运行。

3 VMA的概念。比如只读的数据放在一个VMA,可读可执行的放在一个VMA,所以VMA是进程虚拟空间的连续一段的称呼。

4 链接视图和执行视图。在可执行文件中,从链接视图来看,是按照section来存储的。因为每个section在加载的时候都是占据若干个页,即使某个section只有几十字节也要占据一个页,这样会造成物理内存的浪费。所以实际上,操作系统将权限相同的section都集中到一起,叫做segment。所以从执行视图来看待可执行文件,它是按照segment来划分的。

5 可执行文件中有很多segment,每条segment的内容包含:

(1)p_type: 类型。其中最主要的一个类型是LOAD。只有这个类型的segment是装载到物理内存的

(2)p_offset:在文件中的偏移

(3)p_vaddr:在进程虚拟空间的偏移

(4)p_filesz:在文件中大小

(5)p_memse:在虚拟进程空间大小(这个跟p_filesz一般是相同的)

(6)p_flags:权限,读,写,执行

(7)p_align:对齐属性

6 堆和栈。除了可执行文件中的segment加载之后是一个个的VMA,还有堆和栈也是两个VMA。堆向上增长,栈向下增长

7 segment的对齐。假设每个页的大小是4096字节。其实,可执行文件中的segment在加载后,并不是每个segment的其实地址都是4096的倍数。因为在有很多segment很小的时候,这样也会造成很大的浪费。实际上是这样做的:将各个segment依次连续存储到物理内存,这样的话,某个物理内存中某个页可能包含两个(或者更多)segment,所以这时候会将这个页映射两次,分别到每个segment在进程虚拟空间对应的VMA。(可执行文件有几个segment,在进程虚拟空间就有就有几个VMA)。

8 linux装载elf可执行文件的过程。首先bash通过fork创建一个进程,新进程调用execve执行的elf。总的流程是,读取文件头,根据魔数判断是elf文件,还是java文件,还是什么脚本文件。如果是elf文件,会调用装载elf的程序,这个程序会得到segment的数量,然后装载,将系统调用的返回地址设置为可执行文件的入口地址。然后返回,可执行文件就开始执行了。

时间: 2024-11-12 22:42:28

《程序员自我修养》阅读笔记-可执行文件装载与进程的相关文章

《程序员自我修养》阅读笔记-目标文件里有什么

linux下的目标文件(.o文件)采用ELF格式.目标文件里采用段section的格式存储,比如代码段啊(存代码),数据段啊(初始化了的全局变量和局部静态变量),BSS段啊(未初始化的全局和局部静态变量),只读数据段啊(程序中用到的字符串)等.在所有的段外,有一个重要的结构叫做文件头.所以这里从文件头开始说. 1 文件头主要包含以下内容(没什么用的就不写了): (1)e_ident:这里面一个重要的内容就是魔数和机器的位数.魔数用来标识文件的类型,比如elf啊,a.out啊,MZ啊等.机器位数就

程序员修炼三部曲阅读笔记01

看了程序员的修炼三部曲,感触颇多. 这本书主要分为九章,第一章绪论的部分主要是讲述本身一些结构,以及本书对一般的人的作用.第二章将根据徳雷福斯模型(稍后介绍)将人分为新手到专家的五个阶段.你可以根据描述准确的定为自己所处的阶段.三四五章是将自我认识的部分,主要是正对大脑.第三章讲述的是认识你的大脑,会让你对大脑的工作模式有更好的认识,之后当然是实践的第四章-利用你的右脑.大脑也会范错误,需要我们调试,就是第五章的调试你的大脑.在对大脑有了深刻的认识之后当然是关注如何提高了.后面的几章就是关于提高

一个程序员的奋斗史 阅读笔记

感悟如下: 1.程序员这个职业在业务方面很少有似是而非的内容,是就是,不是就不是.模棱两可是要不得的,打肿脸充胖子更是大忌,不要动不动就写精通 2.优秀的程序员需要不停学习新技术,多看书,多找资料,并在实践在使用自己学到的技术,不吝惜知识的分享 3.环境很重要:大公司学习,只是有深度,小公司学习知识面广,能解决很多基本问题.但公司若想超越对手,则会选择专研度深的程序员.程序员的知识掌握能力应该是金字塔形的 4.英文的重要性,新技术新知识都是先有英文书籍资料(FUCK) 5.应届生提高技术水平是第

《程序员自我修养》阅读笔记-动态链接

1.动态链接的含义.动态链接就是将链接时的重定位推迟到加载时.相比于静态链接,动态链接的一个优点是可以节省内存.因为共享文件的代码可以共享.使用动态链接的时候,可执行文件和共享文件都会加载到内存.但是,如果很多可执行文件都使用了同一个动向文件的时候,共享文件的代码部分只需要装载一次,这样就达到了节省内存的目的.在这里,共享文件的数据部分在每个可执行文件中都要保存一份.所以,共享文件中跟自己的数据有关的代码就可能会变化,因为数据的地址不确定.一旦变化,就不能达到代码共享的目的了.所以,在这里,一般

《程序员自我修养》阅读笔记-静态链接

静态链接分两步,(1)空间与地址分配,(2)符号解析与重定位. 1 空间与地址分配.空间域地址分配有两个含义,一个是输出的可执行文件的空间,一个是装载后的虚拟地址的空间.在这里我们指的是后者.在将多个目标文件(静态)链接成可执行文件的时候,链接器会将所有的代码段放在一起,会将所有的数据段放在一起.放在一起之后,其实每个符号的地址就确定了.比如说有两个目标文件.第一个目标文件中的代码段有一个符号,它的地址为X,即距离代码段的偏移为X.假设经过链接器合并之后,第一个目标文件的代码段的起始地址为A,那

程序员修炼三部曲阅读笔记02

积累经验是学习和成长的关键—我们通过实践的方法学习,效果最好.然而,仅仅一开实践并不能保证成功,必须从实践中有所收获,但是面对一些常见的障碍,我们很难做到这点.你又无法强迫它,过度努力的尝试可能和不去尝试一样糟糕. 本章的开头是引用的马克吐温的话:“我们应该小心翼翼的从实践中获得智慧并且视可而止,否则我们就会线不慎坐在热炉子上的猫一样,它在也不会坐在热炉子上—这还好,但是它也不会坐在冷炉子上了”.好精辟的比喻啊,马克吐温不愧是幽默大师,猫的反应其实和人一样,过度的依赖实践,一旦实践中获得的知识是

程序员的自我修养 学习笔记(4)

可执行文件只有装载到内存以后才能被CPU执行.程序就将是菜谱,CPU就像是厨师,计算机的其他硬件就像是厨具,整个炒菜的过程就是一个进程.同样的一份菜谱,不同人可以做出来不同的味道.这个类比真是巧妙. Linux下面,进程最大使用3G的虚拟空间 Windows下面,进程最大使用2G的虚拟空间 现在计算机,配置超过4G的内存的电脑已经不是不可能了,在这种情况下,32位CPU能够访问到大于4G的空间吗?如果此空间指的是虚拟地址空间,由于32位CPU的指针只能是32位,最大寻址范围是0~4GB.如果此空

一、《程序员的自我修养》笔记-前言

引子:在linux上写了三年多的c了,平时遇到一些编译和链接的问题仍然很是头痛,感觉很无力,好基友推荐<程序员的自我修养>,趁着周末,速速围观. 先记录下作者在书中抛出来的问题 1.为啥程序是从main函数开始执行? 2.PE/ELF文件存的是啥? 3.如何写一个直接跑在未安装os裸机上的程序? 4.目标文件是啥?链接是啥? 5.链接为啥报错? 6.句柄到底是啥? 7.普通c/c++代码如何被编译成牧宝文件及程序在目标文件中如何存储? 8.目标文件如何被链接器链接到一起,并形成可执行文件? 9

C++程序员的自我修养–读书笔记

 1:注意不要反回指向栈内存的指针或引用,因为在函数返回时改内存已经被销毁了 2:C/C++没有办法知道指针所指的内存容量大小 当数组作为参数传递时,数组将退化成相同类型的指针 不要指望要指针参数去申请动态内存,因为函数会为产生一个临时变量指向参数的内存,当函数内分配内存时,将内存的地址赋给了临时参数,而没有给实参赋值,所有实参没有发生任何变化,应该修改的是指针所指的内容,而不是修改指针的指向,所有可以用指向指针的指针 3:重载和内联机制既可用于全局函数也可用于类的成员函数,const和vi