随笔分类 -  程序是如何运行的

摘要:一般来讲,应用程序使用的内存空间里有如下的默认区域: 1 栈:用于维护函数调用的上下文。栈通常在用户空间的最高地址出分配,通常有数兆字节的大小 2 堆:堆是用来容纳应用程序动态分配的内存区域。比如使用malloc和new分配内存就从堆里分配。 3 可执行文件镜像:这里存储着可执行文件在内存里的映射 阅读全文
posted @ 2019-06-25 15:55 red_leaf_412 阅读(4466) 评论(0) 推荐(1) 编辑
摘要:静态链接情况下,操作系统接着就把控制权交给可执行文件的入口地址,然后程序开始执行。但在动态链接情况下,操作系统还不能在装载完可执行文件后就把控制权交给程序。因为可执行文件依赖很多共享对象。这个时候可执行文件中对于很多外部符号的引用还处于无效地址的状态,也就是还没有跟相应的共享对象中的实际位置链接过来 阅读全文
posted @ 2019-06-24 14:17 red_leaf_412 阅读(593) 评论(0) 推荐(1) 编辑
摘要:对于之前的动态链接生成的可执行文件,来看下进程的地址空间分布。首先在pro1.c中加入sleep(-1)进行延时,然后将可执行完文件转入后台处理,通过pid来查询进程的地址空间分布。 cat /proc/3488/maps 558a542d3000-558a542d4000 r-xp 0000000 阅读全文
posted @ 2019-06-13 17:43 red_leaf_412 阅读(464) 评论(0) 推荐(0) 编辑
摘要:相比静态链接,动态链接要复杂得多。但比静态链接更能节省空间。而且对于软件的升级以及插件的使用更快,更方便。比如在静态链接中有一个公共模块common.o 占据1M的空间,使用到common.o模块的程序有100个,那么每个都需要链接common.o。也就是会占据100M空间。如果有更多这样的程序,就 阅读全文
posted @ 2019-04-23 19:41 red_leaf_412 阅读(738) 评论(0) 推荐(0) 编辑
摘要:在一个C语言的运行库中,包含了很多和系统相关的代码,比如输入输出,文件操作,时间日期,内存管理等。比如在输出hello world的程序中我们就需要用到printf.o,文件操作有fread.o, fwrite.o。内存管理有malloc.o。把这些零散的目标文件直接提供给库的使用者,很大程度上会造 阅读全文
posted @ 2018-06-11 22:20 red_leaf_412 阅读(320) 评论(0) 推荐(0) 编辑
摘要:前面介绍了单个.o文件的格式以及里面的内容。那么如果我们有多个目标文件,如何将它们链接成一个可执行的文件呢。多个目标文件就涉及到了链接。我们首先介绍静态链接。 有如下2个文件,test.c/test1.c test.c #include<stdlib.h> #include<stdio.h> ext 阅读全文
posted @ 2018-05-29 11:27 red_leaf_412 阅读(347) 评论(0) 推荐(0) 编辑
摘要:当一个工程中有多个文件的时候,链接的本质就是要把多个不同的目标文件相互粘到一起。就想玩具积木一样整合成一个整体。为了使不同的目标文件之间能够相互粘合,这些目标文件之间必须要有固定的规则才行。比如目标文件B用到了目标文件A中的函数”foo”,那么我们就称目标文件A定义了函数foo,目标文件B引用了函数 阅读全文
posted @ 2018-05-22 22:30 red_leaf_412 阅读(4286) 评论(0) 推荐(0) 编辑
摘要:ELF目标文件格式的最前部是ELF文件头。包含了整个文件的基本属性。比如ELF文件版本,目标机器型号,程序入口地址等。然后是ELF的各个段,其中ELF文件中与段有关的重要结构就是段表。段表描述了ELF文件包含的所有段的信息,比如每个段的段名,段的长度,在文件中的偏移,读写权限及段的其他属性。 一 文 阅读全文
posted @ 2018-05-19 07:01 red_leaf_412 阅读(2065) 评论(0) 推荐(0) 编辑
摘要:我们将之前的代码增加下变量来具体看下 在代码中增加了全局变量以及静态变量,还有一个简单的函数。 #include <stdio.h> int global_var=1; int global_init_var; void func1(int i){ printf("%d\n",i); } int m 阅读全文
posted @ 2018-05-15 22:08 red_leaf_412 阅读(2011) 评论(0) 推荐(0) 编辑
摘要:我们在写程序的时候,windows下通过vs等编译软件,linux通过gcc命令得到程序的可执行文件。在这个过程中,其实大致经历了4个过程。1 预编译 2 编译 3 汇编 4 链接 1 预编译:主要处理那些源代码文件中的以”#”开头的预编译指令,比如”#include”,“#define”等。 2  阅读全文
posted @ 2018-05-11 22:17 red_leaf_412 阅读(2027) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示