记录笔记,因为看了好久还没看完…真的是,但是虽然后面的没看完,但我前面的页快忘完了呀,记录一下吧还是。

一、 温故而知新

  • 从计算机组成原理之类的开始讲,说明这部分还是蛮重要的,虽然也快忘完了。
  • 讲到操作系统,这个的确也与程序运行息息相关。
  • 讲到了一个线程安全与编译器的问题,虽然放在这怪怪的,但是很有趣:
    • 虽然如我们一般所知,加锁是可以在简单情况下保证线程安全的,但是假如编译器为了提高运行速度而优化,假如将一个变量先放在了寄存器中,然后暂时不写回,过了一段时间才写回内存,那么这个就会有问题了,即使正确加锁也线程不安全了。

    • 上面这个问题,C/C++的volatile可以解决,他做两件事:

      1. 阻止编译器为了提高速度将一个变量缓存到寄存器内而不写回。
      2. 阻止编译器调整操作 volatile变量的指令顺序。
    • 再有一种情况是:编译器会优化语句执行的顺序,那么就没有太优雅的方式,通常情况下是调用CPU提供的一条指令,这条指令常常被称为 barrier,barrier指今会阻止CPU将该指令之前的指令交换到barrier之后,反之亦然。


二、 编译和链接

  • 从代码到执行

    • 从hello.c到a.out,有这么几个步骤:分别是预处理( Prepressing),编译(Compilation)汇编(Assembly)和链接( Linking)。
    • 预编译:主要处理代码中以“#”开头的预编译指令。大概就是展开#include,展开#define宏定义,处理#if,#ifdef等条件预编译,删除所有注释,添加行号和文件名标识。.c文件会被预编译成.i文件。
    • 编译:是把预处理的文件进行一系列的 词法分析、语法分析、语义分析、优化操作,生成汇编代码。是程序构建的核心部分。.i 文件会被便以为 .s 文件。
    • 汇编: 汇编器将汇编代码转变为机器可以认识的代码,机器代码,只用按照汇编指令和机器指令的对照表一一翻译即可。输出目标文件 ,即.o 文件。
    • 链接:输出的目标文件运行时,仍然需要其他代码的支持。比如你添加一个头文件,为啥就能调用头文件里的函数了呢?因为有链接器,让你的程序能够找到那些函数、变量等。同样对于调用printf函数也需要链接。
  • 编译部分做了什么?

    • 词法分析:源代码输入进来之后,要分词,比如要把a=2; 分解为a, =, 2三部分,类型是标识符、值符号、数字。
    • 语法分析:对上面的记号进行分析,C语言的一个语句是一个表达式,复杂的语句则是多个表达式的结合,则需要把表达式分开,分解成语法树的方式是利于计算机分析的。
      • 比如:
      • 根据符号的优先级等规则,会被分解为:
    • 语义分析:上面只是分析出了语句是什么样的,并不知道是否合理,有意义。语义分析通常包括声明和类型的匹配,类型转换。
    • 目标代码生成:编译器把优化得来的中间代码转换为虎目标机器代码,根据不同的机器,会有不同的类型程度等。
  • 链接部分做什么?

    • 此处先看静态链接。程序模块化之后,不同模块之间独立编译,链接这个步骤就是将各模块之间组合起来。
    • 链接主要包括了:地址和空间分配、符号决议、重定位这些步骤。
    • 比如我们使用到foo.c中的一个函数foo(),我们main.c中调用时,必须要知道这个foo()函数的地址,编译期间是不知道的,那么需要先搁置(置为0),等最后链接的时候再去修正这些地址。
    • 修正地址的过程叫做重定位,每个地方叫重定位入口

三、目标文件

  • 目标文件是编译完成后的文件,从结构上说已经是可执行文件的格式了,只是还没调整一些符号的地址等。

  • Linux下可执行文件的格式是ELF文件。

  • 目标文件里面有编译过后的代码指令、数据,还有一些链接时用的信息比如符号表、调试信息等。

  • 目标文件一般以段(Segment)的形式存储,比如编译后的机器指令被放在代码段.text,全局变量局部静态变量数据经常被放在数据段.data

  • linux下的目标文件是ELF文件,大致看一下ELF的结构:

    • 文件头:ELF的文件头中定义了ELF魔数、文件机器字节长度数据存储方式、版本、运行平台、AB版本、ELF重定位类型、硬件平台、硬件平台版本、入口地址、程序头入口和长度、段表的位置和长度及段的数量等。这些数值中有关描述ELF目标平台的部分,与我们常见的32位 Intel的硬件平台基本上一样。
    • 段表:我们知道ELF文件中有很多各种各样的段,这个段表(Section Header Table)就是保存这些段的基本属性的结构。段表是ELF文件中除了文件头以外最重要的结构,它描述了ELF的各个段的信息,比如每个段的段名、段的长度、在文件中的偏移、读写权限及段的其他属性。
    • 重定位表:链接器在处理目标文件时,须要对且标文件中某些部位进行重定位,即代码段和数据段中那些对绝对地址的引用的位置。这些重定位的信息都记录在ELF文件的重定位表里面,对于每个须要重定位的代码段或数据段,都会有一个相应的重定位表。、
  • 链接的接口——符号

    • 链接需要处理的就是符号,也就是函数和变量,统称为符号。每一个目标文件会有相应的符号表,值就是符号的地址。
      -定义在本文件的全局符号,可以被其他文件引用;而本文件中引用的全局符号,但没在本文件定义,叫做外部符号。
    • 符号表.symtab会有符号的具体信息。
    • C++由于引进了复杂特性,符号增加了符号修饰,来解决函数重载、继承、虚拟机制等问题导致的符号重名。
  • 目标文件中还有可能保存一些调试信息,调试时必须提前知道源代码和目标代码之间的关系,来设置断点、监控变量。(例如Qt中可以选择Debug版本)但是比较占空间。


阿龙的学习笔记---《程序员自我修养-链接、装载与库》读书笔记(一)相关推荐

  1. 《程序员自我修养》第七章读书笔记

    书还是接上回,本篇主要对第七章的相关内容进行总结.第七章主要对动态链接的相关内容进行分析. 7.1 为什么要动态链接 既然要对动态链接进行分析,首先应对动态链接出现的原因进行一个简单的分析.动态链接从 ...

  2. 【《程序员的自我修养---链接装载于库》读书笔记】可执行文件的装载与进程

    系列文章目录 [<程序员的自我修养-链接装载于库>读书笔记]初探ELF [<程序员的自我修养-链接装载于库>读书笔记]windows PE/COFF [<程序员的自我修养 ...

  3. 阿龙的学习笔记---《程序员自我修养-链接、装载与库》读书笔记(三)

    六.动态链接 动态链接 静态链接可以让模块单独开发测试,但是每个程序内部都需要包含所有的模块,占用空间很大:如果两个程序都需要同一个模块,那么静态链接会有两个重复的模块都在内存中:再者,程序中模块更新 ...

  4. 《程序员的自我修养-链接-装载与库》第三章 目标文件里有什么(1)

    目录 0.引言 1.目标文件的格式 1.1 目标文件的格式及ELF文件格式的文件的分类 1.2 目标文件与可执行文件格式的小历史 2.目标文件是什么样的 2.1 程序与目标文件简介 2.2 BSS历史 ...

  5. 程序员自我修养之链接

    我最近在看PE文件,稍后可能需要dll这些所以顺带看看链接.太久不看这些书,你问我链接是干什么的,我可能会说就是分模块时候用啊,因为一个项目有很多模块,不能写在同一个文件下,所以要把它们链接起来,链接 ...

  6. 程序员自我修养》系统调用与API

    什么是系统调用 在现代的操作系统里,程序运行的时候,本身是没有权利访问多少系统资源的.由于系统有限的资源有可能被多个不同的应用程序同时访问,因此,如果不加以保护,那么各个应用程序难免产生冲突.所以现代 ...

  7. 程序员自我修养的那些事儿

    本篇博客主要是:程序员的自我修养-链接.装载与库的一些学习笔记与心得. 1.首先得注意最大的坑:这本书基于32位系统讲解,因此跟着书本的例子操作一遍的时候,记得要在32位的系统上进行,否则可能出现以下 ...

  8. 一个Java工程师的自我修养_程序员自我修养

    毕业N年,每个人在能力跑道上,有了或大或小的差距.有些人一直在重复的劳动,有些人却能从中总结和解决问题.通过成长日活动,我们或许可以探讨下,怎样共同成长.共同前行,跟"勤奋战术掩盖下的战略懒 ...

  9. 程序员自我修养阅读笔记——运行库

    主要关注程序的启动过程. 1 入口函数和程序初始化 1.1 程序真正的入口   通常写代码时,我们认为程序的入口是main函数,但是实际上有一些现象值得我们怀疑该结论是不是正确的.比如全局变量的初始化 ...

最新文章

  1. 让Chrome成为你的pdf阅读器
  2. 脑科学研究:对于学习来说,休息可能与练习同样重要...
  3. 重设wordpress用户密码
  4. jeecms内容管理系统使用了哪些技术
  5. YOLOv3 学习笔记:大神好贴汇总+自身经验记录
  6. JPG各种输入框样式
  7. C++学习之普通函数指针与成员函数指针
  8. 简述List、Set、Map类型的集合的各自特点
  9. 第八篇:Spring Boot整合Thymeleaf_入门试炼04
  10. php if 单行,php – 单行if语句或if语句没有大括号坏习惯?
  11. java简单的文本编辑器_采用java语言如何建立一个简单的文本编辑器
  12. Extjs 代码拾穗
  13. paddle2.0实现DNN(minst数据集)
  14. linux系统字体文件在哪,linux系统安装字体方法教程介绍
  15. 区块链将成为互联网基础协议,类似于TCP/IP、HTTP
  16. 一本通1373:鱼塘钓鱼(fishing)
  17. 在VMware Server上安装Windows Home Server“ Vail”
  18. 计算机网络-自顶向下笔记-可靠数据传输原理(三种rdt)
  19. Codeforces Round #702 (Div. 3)---C. Sum of Cubes 两种方法 cbrt()函数应用
  20. 基于 Python 的全国空气质量监测与可视化分析平台

热门文章

  1. 从哪里租vps远程桌面服务器,租vps远程桌面服务器
  2. 应对百度“清风算法”的策略和方法
  3. 知心世界姐王瑞平:谷传民与大衣哥朱之文是沟通问题不是人品问题
  4. 爱情如水,宽容是杯~
  5. 计算机网络——第四章 网络层:数据平面
  6. 【数据处理】matlibplot绘图颜色对照表
  7. java简单从一个数据库获取数据,然后插入到另外一个数据库
  8. ubuntu只读文件系统
  9. Linux宝塔控制面板如何实现多个二级域名301重定向跳转
  10. Android 10 新增物理按键