阿龙的学习笔记---《程序员自我修养-链接、装载与库》读书笔记(一)
记录笔记,因为看了好久还没看完…真的是,但是虽然后面的没看完,但我前面的页快忘完了呀,记录一下吧还是。
一、 温故而知新
- 从计算机组成原理之类的开始讲,说明这部分还是蛮重要的,虽然也快忘完了。
- 讲到操作系统,这个的确也与程序运行息息相关。
- 讲到了一个线程安全与编译器的问题,虽然放在这怪怪的,但是很有趣:
虽然如我们一般所知,加锁是可以在简单情况下保证线程安全的,但是假如编译器为了提高运行速度而优化,假如将一个变量先放在了寄存器中,然后暂时不写回,过了一段时间才写回内存,那么这个就会有问题了,即使正确加锁也线程不安全了。
上面这个问题,C/C++的volatile可以解决,他做两件事:
- 阻止编译器为了提高速度将一个变量缓存到寄存器内而不写回。
- 阻止编译器调整操作 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版本)但是比较占空间。
阿龙的学习笔记---《程序员自我修养-链接、装载与库》读书笔记(一)相关推荐
- 《程序员自我修养》第七章读书笔记
书还是接上回,本篇主要对第七章的相关内容进行总结.第七章主要对动态链接的相关内容进行分析. 7.1 为什么要动态链接 既然要对动态链接进行分析,首先应对动态链接出现的原因进行一个简单的分析.动态链接从 ...
- 【《程序员的自我修养---链接装载于库》读书笔记】可执行文件的装载与进程
系列文章目录 [<程序员的自我修养-链接装载于库>读书笔记]初探ELF [<程序员的自我修养-链接装载于库>读书笔记]windows PE/COFF [<程序员的自我修养 ...
- 阿龙的学习笔记---《程序员自我修养-链接、装载与库》读书笔记(三)
六.动态链接 动态链接 静态链接可以让模块单独开发测试,但是每个程序内部都需要包含所有的模块,占用空间很大:如果两个程序都需要同一个模块,那么静态链接会有两个重复的模块都在内存中:再者,程序中模块更新 ...
- 《程序员的自我修养-链接-装载与库》第三章 目标文件里有什么(1)
目录 0.引言 1.目标文件的格式 1.1 目标文件的格式及ELF文件格式的文件的分类 1.2 目标文件与可执行文件格式的小历史 2.目标文件是什么样的 2.1 程序与目标文件简介 2.2 BSS历史 ...
- 程序员自我修养之链接
我最近在看PE文件,稍后可能需要dll这些所以顺带看看链接.太久不看这些书,你问我链接是干什么的,我可能会说就是分模块时候用啊,因为一个项目有很多模块,不能写在同一个文件下,所以要把它们链接起来,链接 ...
- 程序员自我修养》系统调用与API
什么是系统调用 在现代的操作系统里,程序运行的时候,本身是没有权利访问多少系统资源的.由于系统有限的资源有可能被多个不同的应用程序同时访问,因此,如果不加以保护,那么各个应用程序难免产生冲突.所以现代 ...
- 程序员自我修养的那些事儿
本篇博客主要是:程序员的自我修养-链接.装载与库的一些学习笔记与心得. 1.首先得注意最大的坑:这本书基于32位系统讲解,因此跟着书本的例子操作一遍的时候,记得要在32位的系统上进行,否则可能出现以下 ...
- 一个Java工程师的自我修养_程序员自我修养
毕业N年,每个人在能力跑道上,有了或大或小的差距.有些人一直在重复的劳动,有些人却能从中总结和解决问题.通过成长日活动,我们或许可以探讨下,怎样共同成长.共同前行,跟"勤奋战术掩盖下的战略懒 ...
- 程序员自我修养阅读笔记——运行库
主要关注程序的启动过程. 1 入口函数和程序初始化 1.1 程序真正的入口 通常写代码时,我们认为程序的入口是main函数,但是实际上有一些现象值得我们怀疑该结论是不是正确的.比如全局变量的初始化 ...
最新文章
- 让Chrome成为你的pdf阅读器
- 脑科学研究:对于学习来说,休息可能与练习同样重要...
- 重设wordpress用户密码
- jeecms内容管理系统使用了哪些技术
- YOLOv3 学习笔记:大神好贴汇总+自身经验记录
- JPG各种输入框样式
- C++学习之普通函数指针与成员函数指针
- 简述List、Set、Map类型的集合的各自特点
- 第八篇:Spring Boot整合Thymeleaf_入门试炼04
- php if 单行,php – 单行if语句或if语句没有大括号坏习惯?
- java简单的文本编辑器_采用java语言如何建立一个简单的文本编辑器
- Extjs 代码拾穗
- paddle2.0实现DNN(minst数据集)
- linux系统字体文件在哪,linux系统安装字体方法教程介绍
- 区块链将成为互联网基础协议,类似于TCP/IP、HTTP
- 一本通1373:鱼塘钓鱼(fishing)
- 在VMware Server上安装Windows Home Server“ Vail”
- 计算机网络-自顶向下笔记-可靠数据传输原理(三种rdt)
- Codeforces Round #702 (Div. 3)---C. Sum of Cubes 两种方法 cbrt()函数应用
- 基于 Python 的全国空气质量监测与可视化分析平台