程序编译链接

  1. 问:程序链接过程是把不同的程序段链接起来,是不是因为有的函数是用单独的头文件写着,所以需要include,链接的过程就是找到这些include文件然后把函数复制到代码中呀
    答:首先第一句话,程序链接过程是将多个目标文件、库拼合成最终的可执行文件,程序生成可执行文件的过程如下:


    image.png

    事实上处理#include是在预处理阶段就完成了,怎么完成?将被包含的文件插进到该指令的位置。
    这时问题又来了,上图所示的几个过程分别是什么意思?
    预处理:主要是做一些代码文本的替换工作。删除所有的注释//与/* */、将所有的#define删除,并展开所有的宏定义、处理#include预编译指令,将被包含的文件插进到该指令的位置。
    编译:把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生成汇编代码。
    汇编:汇编代码->机器指令。
    链接:这里讲的链接,严格说应该叫静态链接。多个目标文件、库->最终的可执行文件(拼合的过程)。

  2. 问:那每次链接的时候如果调用了很多外部函数,那链接的时候不是要浪费很多时间在复制这些函数上?
    答:静态链接确实是将函数的代码从其所在地(目标文件或静态链接库中)拷贝到最终的可执行程序中。动态链接不是的。

  3. 问:动态链接和静态链接我还是没弄明白,静态链接是有几个代码调用这个函数,那这个函数就要复制几份;动态链接就是用到这个函数的时候调用这个函数,这个时候难道不复制?那是怎么用的,要是多个程序都要动态链接这个函数那怎么弄?
    答:动态链接库只提供符号表和其他少量信息用于保证所有符号引用都有定义,保证编译顺利通过。动态链接器(ld-linux.so)链接程序在运行过程中根据记录的共享对象的符号定义来动态加载共享库,然后完成重定位。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码,函数代码并没有复制到可执行文件中来。 而静态链接在执行前进行了拷贝。多个程序要链接一个函数?因为代码段在内存中的权限都是为只读的,所以当多个应用程序加载同一个代码段的时候,不用担心应用程序会修改代码段。多个程序调用一个函数时,先把变量和函数拿到,然后保存在自己的线程栈中,相互不影响。

  4. 问:给我解释下虚拟内存到底咋回事儿,看书看不懂
    答:虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。目前,大多数操作系统都使用了虚拟内存,如Windows家族的“虚拟内存”;Linux的“交换空间”等。
    什么情况下硬盘会拿来当内存使用?当内存耗尽时,电脑就会自动调用硬盘来充当内存,以缓解内存的紧张。它将计算机的内存和硬盘上的临时空间组合。当RAM运行速率缓慢时,它便将数据从内存移动到称为“分页文件”的空间中。
    虚拟内存跟物理内存有啥区别和联系?
    虚拟内存地址到实际的物理内存会有一个翻译的过程,虚拟内存中连续的地址在物理内存中就不一定连续。所有进程共享同一物理内存,每个进程只把自己目前需要的虚拟内存空间映射并存储到物理内存上。进程要知道哪些内存地址上的数据在物理内存上,哪些不在,还有在物理内存上的哪里,需要用页表来记录。页表的每一个表项分两部分,第一部分记录此页是否在物理内存上,第二部分记录物理内存页的地址。


    Paste_Image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容