链接器

计算机系统大作业

半城伤御伤魂 提交于 2020-01-27 00:59:48
计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 计算机类 学   号 1180300412 班   级 1803004 学 生 yiguanghui 指 导 教 师 计算机科学与技术学院 2019年12月 摘 要 关键词:计算机系统、编译链接、异常控制流、虚拟内存 摘要:本文较详细地跟踪介绍了hello.c在Linux下的生命周期,从被程序员创建,到在系统上运行,然后输出简单的消息,最后终止。本文通过计算机系统课程中相关的知识来分析hello.c在Linux开发工具下经历预处理、编译、汇编、链接、加载、执行、终止、回收等过程和结果,跟踪程序的链接、进程创建及加载、虚拟内存转换、高速缓存访问、异常控制流、I/O管理等过程。 目 录 第1章 概述… - 4 - 1.1 Hello简介… - 4 - 1.2 环境与工具… - 4 - 1.3 中间结果… - 4 - 1.4 本章小结… - 4 - 第2章 预处理… - 5 - 2.1 预处理的概念与作用… - 5 - 2.2在Ubuntu下预处理的命令… - 5 - 2.3 Hello的预处理结果解析… - 5 - 2.4 本章小结… - 5 - 第3章 编译… - 6 - 3.1 编译的概念与作用… - 6 - 3.2 在Ubuntu下编译的命令… - 6 - 3.3 Hello的编译结果解析… - 6 - 3.4

C++11 外部模板

隐身守侯 提交于 2020-01-24 03:00:54
【1】引入外部模板为了解决什么问题? “外部模板”是C++11中一个关于模板性能上的改进。实际上,“外部”(extern)这个概念早在C的时候已经就有了。 常见的情况,在一个文件a.c中定义了一个变量int i,而在另外一个文件b.c中想使用它,这个时候就会在没有定义变量i的b.c文件中做一个外部变量的声明。比如: // 声明在b.c文件中 extern int i; 这样做的好处是,在分别编译了a.c和b.c之后,其生成的目标文件a.o和b.o中只有i这个符号(可简单理解为变量)的一份定义。 具体地,a.o中的i是实在存在于a.o目标文件的数据区中的数据,而在b.o中,只是记录了i符号会引用其他目标文件中数据区中的名为i的数据。 这样一来,在链接器(通常由编译器代为调用)将a.o和b.o链接成单个可执行文件(或者库文件)c的时候,c文件的数据区也只会有一个i的数据(供a.c和b.c的代码共享)。 而如果b.c中我们声明int i的时候不加上extern的话,那么i就会实实在在地既存在于a.o的数据区中,也存在于b.o的数据区中。 那么链接器在链接a.o和b.o的时候,就会报告错误,因为无法决定相同的符号是否需要合并。 而对于函数模板来说,现在我们遇到的几乎是一模一样的问题。 不同的是,发生问题的不是变量(数据),而是函数(代码)。这样的困境是由于模板的实例化带来的。

链接脚本是做什么的?

大兔子大兔子 提交于 2020-01-15 16:59:36
链接脚本其实是个规则文件,它是程序员用来指挥链接器工作的。链接器会参考链接脚本,并且使用其中规定的规则来处理.o文件中那些段,将其链接成一个可执行程序。 链接脚本的关键内容有2部分:段名(用来在.o文件里面去定位这一段)+地址(作为链接地址的内存地址),段名是用来找原材料的,地址是用来找位置的,把这个段名放到这个地址去就好了。 链接器相当于一个打包器,你的段名告诉它打包什么物品,地址告诉它打包到什么地方去。最后所有的东西都放在该在的位置了,链接就完成了。 链接脚本的理解: SECTIONS {} 这个是整个链接脚本 . 点号在链接脚本中代表当前位置。 = 等号代表赋值 来源: CSDN 作者: 陶通宁 链接: https://blog.csdn.net/taotongning/article/details/103962266

20-链接过程简介

你离开我真会死。 提交于 2020-01-11 15:15:25
注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。 测试环境:Ubuntu 10.10 GCC版本:4.4.5 一、问题... 工程中的每个C语言源文件被编译后生产目标文件,这些目标文件如何生存最终的可执行程序? 二、链接器的意义 链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接。 注:这样就支持了多种开发语言混合开发项目。 三、模块链接 1)静态链接 - 由链接器在链接时将库的内容直接加入到可执行程序中。 链接时就将库加载到可执行程序(运行程序前就已经被加载完毕)。 2) linux下静态库的创建和使用 - 编译静态库源码: gcc -c lib.c -o lib.o - 生成静态库文件: ar -q lib.a lib.o //ar:打包,lib是打包 //创建静态库lib.a - 使用静态库编译: gcc main.c lib.a -o main.out 编程实验 静态链接示例 20-1.c #include <stdio.h> extern char* name(); extern int add(int a, int b); int main() { printf("Name: %s\n", name()); printf("Result: %d\n", add(2, 3)); return 0; } slib.c char

第一周 ch01 课下测试

[亡魂溺海] 提交于 2020-01-09 00:08:51
1.Amdahl定律说明,我们对系统的某个部分做出重大改进,可以显著获得一个系统的加速比。(B) A .正确 B .错误 解析:Amdahl定律,该定律的主要思想是,当我们对系统的某个部分加速时,其对整个性能的影响取决于该部分的重要性和加速程度。 2.Linux中,内核虚拟内存在虚拟地址空间的低端。(B) A . 正确 B . 错误 解析:由上图可知内核虚拟内存在虚拟地址空间的最顶端而不是最低端 3.实现进程这个抽象概念需要低级硬件和操作系统软件之间的紧密合作。(A) A . 正确 B . 错误 解析:进程是操作系统对正在运行的程序的一种抽象。一个系统上可以同时运行多个进程,每个进程好像独占的使用硬件。所谓并发,是说一个进程的指令和另一个进程的指令交错执行。操作系统实现这种交错执行的机制称为上下文切换。操作系统跟踪进程运行所需的所有状态信息(也就是上下文),任何一个时刻,处理器只能运行一个进程。当操作系统决定要把控制权从当前进程转移到一个新进程时,就要进行上下文切换,即保存当前进程的上下文,恢复新进程的上下文,然后将控制权转交给新进程,新进程就从上次停止的地方开始执行。实现进程这个抽象概念需要低级硬件和操作系统软件之间的紧密合作 4.操作系统有两个基本功能:防止硬件被滥用;向应用供一致的机制来控制低级硬件设备。实现这两个功能相关的抽象有(ACD) A . 文件 B . 虚拟机 C

Visual Studio 2019+Kinect2.0+opencv3.4.7工程配置

戏子无情 提交于 2020-01-07 17:56:32
新建一个控制台工程应用。 安装好Kinect2.0 SDK 和 opencv3.4库。 配置工程如下: 一、Kinect2.0的工程配置 1、为了正确编译,选择在debug x64的环境下编译 2、打开工程的属性,确认是否是debug 和 x64模式下 3、在【c/c++】----【常规】----【附加包含目录】中 添加【对应的kinect路径下的inc文件的地址】 ————————————要明确自己安装Kinect SDK的路径—————————————— 4、在【链接器】----【常规】-----【附加库目录】下添加 【自己对应的kinect安装地址的x64的文件夹的目录】 5、在【链接器】-----【输入】----【附加依赖项】中添加kinect20.lib文件 【20表示的是kinect 2.0 其他版本不清楚 建议上网搜索一下】 到这里,kinect2.0的环境配置基本完成。 二、opencv3.4.7的环境配置 非常重要的一点,要清楚自己安装opencv库的路径,我这里是安装到了E盘。 1、点击【我的电脑】右键-----【属性】----【高级系统设置】-----【进入环境变量】 2、在【系统变量】----【path】中添加一条路径,是【对应的自己的opencv安装的路径中bin文件夹所在的地址】 3、打开工程的属性,在【VC++目录】-----【包含目录】---

pdb文件 小结

泄露秘密 提交于 2019-12-29 05:48:58
.pdb文件,是VS生成的用于调试的符号文件(program database),保存着调试的信息。在VS的工程属性,C/C++,调试信息格式,设置/Zi,那么VS就会在构建项目时创建PDB文件。 在这里要区分两种情况: 1、构建静态库时,可以在工程属性 –> C/C++ –> 输出文件 –> 程序数据库名 设置生成的pdb文件名称,如果不指定,默认是生成为VCx0.pdb,这里x是VS版本号,例如用VS2005,就会生成VC80.pdb。这里就会产生一个疑问,编译静态库时默认生成的.pdb文件名字都一样,那引用这个静态库的项目最后能找到正确的.pdb文件吗?答案是肯定的,因为VS会在生成的文件中嵌入 .pdb 文件的路径。 举个例子,在Project/ToolA下,构建了一个静态库ToolA.lib,对应生成一个vc80.pdb,同样在在Project/ToolB下,构建了一个静态库ToolB.lib,对应生成一个vc80.pdb。然后最终的工程Work.exe同时链接了这两个静态库.这时,生成Work.pdb的时候,就会在ToolA.lib中找到它对应的符号文件路径Project/ToolA/vc80.pdb,以及ToolB.lib对应的符号文件路径Project/ToolB/vc80.pdb,合并生成最终工程的Work.pdb。 2、构建可执行文件或动态库,这种情况下

模板的声明和实现为何要放在头文件中?

人盡茶涼 提交于 2019-12-21 07:23:00
源: http://blog.csdn.net/lqk1985/archive/2008/10/24/3136364.aspx 如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 PM 发表人: Nemanja Trifunovic 前言 常遇到询问使用模板到底是否容易的问题,我的回答是:“模板的使用是容易的,但组织编写却不容易”。看看我们几乎每天都能遇到的模板类吧,如STL, ATL, WTL, 以及Boost的模板类,都能体会到这样的滋味:接口简单,操作复杂。 我在5年前开始使用模板,那时我看到了MFC的容器类。直到去年我还没有必要自己编写模板类。可是在我需要自己编写模板类时,我首先遇到的事实却是 “传统”编程方法(在*.h文件声明,在*.cpp文件中定义)不能用于模板。于是我花费一些时间来了解问题所在及其解决方法。 本文对象是那些熟悉模板但还没有很多编写模板经验的程序员。本文只涉及模板类,未涉及模板函数。但论述的原则对于二者是一样的。 问题的产生 通过下例来说明问题。例如在array.h文件中有模板类array: // array.h template <typename T, int SIZE> class array { T data_[SIZE]; array (const array& other); const array& operator =

ELF文件格式

点点圈 提交于 2019-12-20 19:32:46
ELF头 Object目标文件类型 Object文件格式 数据表示 ELF Header结构体 e_ident e_type类型 e_machine ELF节 section头表结构体 section介绍 符号表 字符串表 符号值 重定位 重定位类型 Linux命令行 ELF头 Object目标文件类型 一个可重定位(relocation)文件保存着代码和适当的数据,用来和其他的object文件一起创建一个可执行文件或一个共享文件。 一个可执行(executable)文件保存着一个用来执行的程序,该文件指出exec(BA_OS)如何创建程序进程映像。 一个共享object文件保存着代码和合适的数据,用来被链接器链接。第一个链接器[ld(SD_CMD)],可以和其他的可重定位和共享object文件来创建其他的object;第二个动态链接器,联合一个可执行文件和其他共享object文件来创建一个进程映像。 Object文件格式 数据表示 ELF Header结构体 # define EI_NIDENT 16 typedef struct { unsigned char e_ident [ EI_NIDENT ] ; Elf32_Half e_type ; Elf32_half e_machine ; Elf32_Word e_version ; //目标文件的版本,若为0

描述编译和链接过程

谁都会走 提交于 2019-12-20 18:04:09
原文摘自: http://www.cppblog.com/shifan3/archive/2007/01/05/17325.html [yc]详解link 详解link 有些人写C/C++(以下假定为C++)程序,对unresolved external link或者duplicated external simbol的错误信息不知所措(因为这样的错误信息不能定位到某一行)。或者对语言的一些部分不知道为什么要(或者不要)这样那样设计。了解本文之后,或许会有一些答案。 首先看看我们是如何写一个程序的。如果你在使用某种IDE(Visual Studio,Elicpse,Dev C++等),你可能不会发现程序是如何组织起来的(很多人因此而反对初学者使用IDE)。因为使用IDE,你所做的事情,就是在一个项目里新建一系列的.cpp和.h文件,编写好之后在菜单里点击“编译”,就万事大吉了。但其实以前,程序员写程序不是这样的。他们首先要打开一个编辑器,像编写文本文件一样的写好代码,然后在命令行下敲 cc 1.cpp -o 1.o cc 2.cpp -o 2.o cc 3.cpp -o 3.o 这里cc代表某个C/C++编译器,后面紧跟着要编译的cpp文件,并且以-o指定要输出的文件(请原谅我没有使用任何一个流行编译器作为例子)。这样当前目录下就会出现: 1.o 2.o 3.o 最后