详解程序转入和链接

概要

程序执行过程中,一共经历了四步,最终生成可执行的目标文件hello.exe,这四个步骤分别是:预处理,编译,汇编,链接

在这里插入图片描述

预处理:预处理器(cpp)预处理就是把程序中引用文件插入到当前文本文件中,比如开头的#include <stdio.h>,包含了stdio.h文件,预处理命令就会读取stdio.h文件的内容,把它插入到当前的hello.c文件中,生成一个叫hello.i的文件;
编译:编译器(ccl) 编译这个阶段就比较重要了,我们平常使用的高级语言有很多种,C,C++,Java……,每种语言书写表达的方式不尽相同,如何把这些不同的语言统一转换成一种格式,让计算机理解他们要做的都是同一件事情呢?那就要靠编译器了!这里不同的语言使用的编译器也不相同,但要实现的功能是一致的。编译器中存在一个叫做“汇编语言程序”的东西,汇编语言大概是最接近机器语言的了,编译器要做的事情,就是把预处理完毕的hello.i文件翻译成汇编语言,生成的文件叫做hello.s;
汇编:汇编器(as)要做的就是把编译生成的汇编语言,翻译成机器能读懂的二进制语言,叫做hello.o;
链接:链接器(ld)看上图中代码调用了一个printf()函数,这是C编译器中的标准C库中的一个函数,单独保存在一个已经预编译好的printf.o文件中,链接器要做的就是把printf.o文件合并到我们的hello.o文件中,最终生成了可执行文件hello;

在这里插入图片描述
中间红线为分界线,左边部分为程序做的事,右边为OS做的事–装入。

程序的装入和链接

编译程序:将用户源代码编译成若干个目标模块;
链接程序:将一组目标模块及它们所需要的库函数链接在一起,形成一个完整的装入模块
装入程序:将装入模块装入内存。

程序的装入

  • 逻辑地址空间(或地址空间):由程序中逻辑地址组成的地址范围。

【注意】用户程序经编译之后的每个目标模块都以0为基地址顺序编址,这种地址称为相对地址

  • 绝对地址(物理地址):内存中各物理存储单元的地址是从统一的基地址顺序编址,这种地址称为绝对地址

绝对装入方式

程序编译时,如果知道程序将驻留在内存的什么位置(起始地址),那么编译生成的目标代码,将采用绝地地址进行编址,即起始地址不从0开始,从上面所知的内存起始地址开始编址。

例如:事先已知用户程序(进程)驻留在从1000号单元处开始的位置,则编译程序所产生的目标模块(即装入模块)便从1000处开始向上扩展:
在这里插入图片描述
由于采用的是绝对地址,所以将装入模块直接装入内存即可,无需进行地址变换。 但是,只适合早期对硬件直接编程、单道环境下使用。

可重定位装入方式(静态重定位)

出现:

- 编译时将程序装入指定的内存空间,必须需要程序员熟悉内存的使用情况
- 绝对装入方式只能将目标模块装入到内存中事先指定的位置。而在多道程序环境下,编译程序不可能预知所编译的目标模块应放在内存的何处
- 可重定位方式可根据内存的当前情况,将装入模块装入到内存的适当位置

原理:

源程序编译生成的目标模块都采用相对地址进行编址,即每个模块都从0开始编址,当然链接后的模块也采用相对地址编址
在这里插入图片描述
将装入模块装入内存后,模块中的程序和数据等,在内存中都将具有一个物理地址,此物理地址是相对于内存的起始地址进行编址的,所以与原先模块中的逻辑地址(相对于模块的起始地址进行编址)不同,所以为了得到物理地址需要对逻辑地址进行改变。而此地址变化的过程就叫做重定位,又因为地址变换通常是在装入时一次完成的,以后不再改变,故称为静态重定位。如下图:
在这里插入图片描述

动态运行时装入方式(动态重定位)

把相对地址到绝对地址的转换推迟到程序真正执行时才进行。在运行时地址映射。实际运行中往往会需要程序在内存中的各位置移动,即经常需要重定位到不同的物理地址上。 这种运行时移动程序要求地址变换要快速,实现时一般依靠硬件地址变换机构——一个重定位寄存器。
在这里插入图片描述

程序的链接

静态链接方式

一次链接完毕:在程序运行之前,先将各目标模块及它们所需的库函数,链接成一个完整的装配模块,以后不再拆开。我们把这种事先进行链接的方式称为静态链接方式。

装入时动态链接

边装边运行:用户源程序经编译后所得的目标模块,是在装入内存时边装入边链接的,即在装入一个目标模块时,若发生一个外部模块调用事件,将引起装入程序去找出相应的外部目标模块,并将它装入内存。

运行时动态链接

按需取用:在执行过程中,当发现一个被调用模块尚未装入内存时,立即由OS去找到该模块并将之装入内存,把它链接到调用者模块上。凡在执行过程中未被用到的目标模块,都不会被调入内存和被链接到装入模块上,这样不仅可加快程序的装入过程,而且可节省大量的内存空间。
在这里插入图片描述

参考:
https://www.cnblogs.com/sunbines/p/9237604.html
https://www.cnblogs.com/suncoolcat/p/3358053.html
https://edu.51cto.com/center/course/lesson/index?id=396796(推荐本视频,如果有不懂的基本可以解决,视频例子举得也很好)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章