【深入理解计算机系统】链接

静态链接器以一组可重定位目标文件和命令行参数作为输入,生成一个完全链接的可以加载和运行的可执行目标文件作为输出。为了构造可执行文件,链接器必须完成两个主要任务:

1、符号解析:目标文件定义和引用符号,符号解析将每个符号引用刚好和一个符号定义联系起来

2、重定位:编译器和汇编器生成从地址0开始的代码和数据section,链接器通过把每个符号定义与一个存储器位置联系起来,然后修改所有对这些符号的引用,使得它们指向这个存储器位置

目标文件三种形式:可重定位目标文件、可执行目标文件、共享目标文件。编译器和汇编器生成可重定位目标文件(包括共享目标文件),链接器生成可执行目标文件。

现代UNIX系统的目标文件格式是ELF格式(executable and linkable Format)

一个典型的ELF可重定位目标文件包含下面几个段(section):

.text: 已编译程序的机器代码

.data: 已初始化的全局c变量,局部c变量在运行时保存在栈中,既不出现在.data段中,也不出现在.bss段中

.bss: 未初始化的全局c变量,在目标文件中这个段不占据实际的空间,它仅仅是一个占位符,目标文件格式区分初始化和未初始化变量是为了空间效率,在目标文件中,未初始化变量不需要占据任何实际的磁盘空间。

.symtab: 一个符号表,存放在程序中定义和引用的函数和全局变量的信息。

每个可重定位目标模块m都有一个符号表,它包含模块所定义和引用的符号的信息,在链接器的上下文中,有三种不同的符号:

1、由m定义并能被其他模块引用的全局符号,对应于非静态的c函数以及被定义为不带static属性的全局变量

2、由其他模块定义并被模块m引用的全局符号,对应于定义在其他模块中的c函数和变量

3、只被模块m定义和引用的本地符号,对应于带static属性的c函数和全局变量,这些符号在本模块到处都可以访问,但是不能被其他模块引用。

注意,定义为带有static属性的本地局部变量不在栈中管理,编译器在.data和.bss中为每个定义分配空间,并在符号表中创建一个有唯一名字的本地链接器符号。

c语言中static属性在模块内部隐藏变量和函数声明,类似c++中public和private声明一样。c源代码文件扮演模块的角色,任何声明带有static属性的全局变量或者函数都是模块私有的,任何声明为不带static属性的全局变量和函数都是公共的,可以被其他模块访问。

c++和Java中能使用重载函数,是因为编译器将每个唯一的方法和参数列表组合编码成一个对链接器来说唯一的名字,这个编码过程为mangling,相反的过程为demangling

时间: 2024-10-28 08:34:53

【深入理解计算机系统】链接的相关文章

《深入理解计算机系统》读书笔记第七章——链接

<深入理解计算机系统>第七章 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(或拷贝)到存储器并执行. 链接的时机 编译时,也就是在源代码被翻译成机器代码时 加载时,也就是在程序被加载器加载到存储器并执行时. 运行时,由应用程序执行. 在现代系统中,链接是由链接器自动执行的. 7.1 编译器驱动程序 编译系统提供编译驱动程序——调用语言预处理器.编译器.汇编器和链接器. (1)运行C预处理器:源程序main.c->ASCII码中间文件main.i (2)

《深入理解计算机系统》第七章 链接

<深入理解计算机系统>第七章 链接 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(货被拷贝)到存储器并执行. 链接的时机 编译时,也就是在源代码被翻译成机器代码时 加载时,也就是在程序被加载器加载到存储器并执行时 运行时,由应用程序执行 链接器使分离编译称为可能. 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(或拷贝)到存储器并执行. 链接可以执行于编译时,也就是在源代码被翻译成机器代码时:也可以执行于加载时,也就是在程序

深入理解计算机系统9个重点笔记

引言 深入理解计算机系统,对我来说是部大块头.说实话,我没有从头到尾完完整整的全部看完,而是选择性的看了一些我自认为重要的或感兴趣的章节,也从中获益良多,看清楚了计算机系统的一些本质东西或原理性的内容,这对每个想要深入学习编程的程序员来说都是至关重要的.只有很好的理解了系统到底是如何运行我们代码的,我们才能针对系统的特点写出高质量.高效率的代码来.这本书我以后还需要多研究几遍,今天就先总结下书中我已学到的几点知识. 重点笔记 编写高效的程序需要下面几类活动: 选择一组合适的算法和数据结构.这是很

《深入理解计算机系统》 Chapter 7 读书笔记

<深入理解计算机系统>Chapter 7 读书笔记 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(货被拷贝)到存储器并执行. 链接的时机 编译时,也就是在源代码被翻译成机器代码时 加载时,也就是在程序被加载器加载到存储器并执行时 运行时,由应用程序执行 链接器使分离编译称为可能. 一.编译器驱动程序 大部分编译系统提供编译驱动程序:代表用户在需要时调用语言预处理器.编译器.汇编器和链接器. 1.将示例程序从ASCⅡ码源文件翻译成可执行目标文件的步骤 (1)运

深入理解计算机系统读书笔记一 ---&gt; 计算机基础漫游

一.程序编译的不同阶段. 通常我们是以高级程序开发易于阅读的代码,我们通过语法规则推断代码的具体含义.但是计算机执行代码的时候就需要把代码解析成既定的可执行问题,计算机是如何处理的呢?这里以C语言hello.c文件为例来说明中间过程. #include <stdio.h> int main() { printf("hello world!\n"); } 先上张图. C语言源程序----预处理解析头文件和函数  --- 编译器解析成汇编语言 ---   翻译机器语言指令,打包

20135302魏静静——《深入理解计算机系统》第7章 学习笔记

<深入理解计算机系统>第7章   链接 本章主要内容: 链接——静态链接.动态链接(链接又包括两个主要任务:符号解析和重定位) 符号——全局符号和本地符号.符号表.符号解析 链接文件的创建及引用——gcc.ar rcs.sharedj及fPIC命令参数 重定位——重定位条目.重定位符号引用(PC相对引用和绝对引用) 目标文件——可重定位目标文件(其中又详细介绍了ELF可重定位文件的结构及格式).可执行目标文件.共享目标文件 链接(linking)是将各种代码和数据部分收集起来并组合成为一个单一

《深入理解计算机系统》(1)

typedef unsigned char* byte_pointer; void show_bytes(byte_pointer start, int len) { for (int i = 0; i < len; i++) { printf("%2x", start[i]); } cout<<endl; } int _tmain(int argc, _TCHAR* argv[]) { char* buf = "0x11EG"; char* st

深入理解计算机系统(1.1)------Hello World 是如何运行的

上一篇序章我谈了谈 程序员为啥要懂底层计算机结构 ,有人赞同也有人反对,但是这并不影响 LZ 对深入理解计算机系统研究的热情.这篇博客以案例驱动的模式,通过跟踪一个简单 Hello World 程序的生命周期开始系统的学习,包括它被程序员创建,到在系统上运行,输出简单的消息,然后终止.LZ 将沿着这个程序的声明周期,先简要的介绍一些逐步出现的关键概念.专业术语以及组成部分.后面将会详细展开. 1.计算机系统 我们知道计算机系统是由硬件和软件组成的.它们共同工作来运行应用程序.虽然系统的实现方式随

电子书 深入理解计算机系统.pdf

内容简介 和第2版相比,本版内容上*大的变化是,从以IA32和x86-64为基础转变为完全以x86-64为基础.主要更新如下: 基于x86-64,大量地重写代码,首次介绍对处理浮点数据的程序的机器级支持. 处理器体系结构修改为支持64位字和操作的设计. 引入更多的功能单元和更复杂的控制逻辑,使基于程序数据流表示的程序性能模型预测更加可靠. 扩充关于用GOT和PLT创建与位置无关代码的讨论,描述了更加强大的链接技术(比如库打桩). 增加了对信号处理程序更细致的描述,包括异步信号安全的函数等. 采用

计算机编程基础之深入理解计算机系统1

目录 概述——<深入理解计算机系统> 计算机系统漫游 信息的表示和处理 概述——<深入理解计算机系统> Computer Systems A Programmers Perspective  英文名 计算机系统漫游 本章简介 当系统上执行hello程序时,系统发生了什么以及为什么会这样 信息就是位+上下文 源程序(或者源文件) hello.c,实际上是由值0和1组成的位(bit)序列,8个位被组织成一组,成为字节.每个字节表示程序中某个文本字符,大部分的现代系统都使用ASCII标准