zoukankan      html  css  js  c++  java
  • 编译-实践中的编译过程

    https://mp.weixin.qq.com/s/6dJGqQAtxcUfHLOTvhdJOA

     
    实际实践中,为了提高代码复用和灵活性,除了编译过程之外,会增加一些操作过程。
    下面以C语言为例,逐个简介。
     
    二. 编译
     
    编译原理的各个过程在这个阶段执行,把C语言代码源文件转换成为目标文件。目标文件即是编译生成的最终代码。
    编号为“二”是指编译这个过程在第二步执行。放在最开始,是为了承接上一篇编译原理。
     
    一. 预处理
     
    C语言的预处理,比编译过程要简单,可以简单的理解为文本替换。虽然只是简单的一步文本替换,但是为代码编写提供了很大的灵活性和扩展性。
     
    gcc -E选项,可以把.c转换为.i,检查宏替换是否正确。
     
    三.链接
     
    链接把多个源文件编译生成的目标文件链接到一起,生成可执行文件,如exe和elf格式可执行文件。
    因为多个源文件之间存在符号引用问题,所以在编译阶段并不会也无法确定符号的最终地址,在链接生成可执行文件时才确定。
     
    四.库
     
    为了提高代码复用度,很多常用的函数如字符串操作,内存拷贝等,并不会每一程序都会重写一遍,而是事先把这些函数编译成库。在链接应用程序的时候,直接把这些库作为目标文件,一起链接。
    如libc, libc++, uClibc等。
     
    库分为静态库和动态库。
    静态库在链接时会拷贝到可执行程序中,程序运行时不再需要该库文件;
    动态库在链接时只是记录符号引用信息,程序运行时需要能够在库文件查找路径(LD_LIBRARY_PATH)中找到对应的库,才能够成功执行。
     
    五.加载器
     
     
    应用程序一般由操作系统加载执行,操作系统加载可执行程序时,会依据可执行程序的格式(ELF/EXE),把可执行文件中不同的段加载到相应的地址区间(线性地址区间,非物理地址)。如果可执行程序依赖某个库文件(动态库),则在系统库文件路径中查找所依赖的库,然后把库文件加载进程序地址区间。然后替换程序中所引用的库文件的符号为库中相应函数加载的地址。所有符号替换完成后,程序即可开始执行。
     
    操作系统本身也会提供很多系统库供进程使用,并且使用范围很广。操作系统并不会把这些苦加载到每个进程的地址空间中,而是在物理内存中加载一次,然后把这块内存区间映射到所有进程的地址区间中。这样既可以减少进程加载的时间,也可以防止内存中加载多份相同的库,虚耗内存。
     
     
  • 相关阅读:
    H3CNE学习2,3 TCP-IP模型
    H3CNE学习1 课程简介
    TCPDUMP抓包学习
    Kubernetes 学习26 基于kubernetes的Paas概述
    Kubernetes 学习25 创建自定义chart及部署efk日志系统
    Linux https认证原理
    Kubernetes 学习24 helm入门
    【MySQL基础总结】索引的使用
    【MySQL基础总结】常用函数库
    【MySQL基础总结】运算符的使用
  • 原文地址:https://www.cnblogs.com/wjcdx/p/9321154.html
Copyright © 2011-2022 走看看