程序的链接——总述

程序的链接

程序的链接相当重要,是代码到最后可执行文件的最后一步。理解程序的链接非常重要,让我们开始吧。

理解程序的链接之前我们得弄清楚程序的链接之前发生了什么

在链接之前有三步预处理、编译和汇编

预处理

主要用于 C 语言编译器对各种预处理命令进行处理。比如

  • 头文件的包含
  • 宏定义的扩展
  • 条件编译的选择(#ifdef)

举个栗子: ̄へ ̄

对 include 的预处理就是把 .h 里面的插进这个代码里面。

可以用 gcc -E main.c -o main.i 看预处理之后的文件

编译

简单来说就是把 main.i 里面的代码转换成汇编代码

gcc -S main.i -o main.s

也可以

gcc -S main.c -o main.s

汇编

汇编的功能就是把生成的汇编语言代码转换成机器语言代码。因为通常最终的可执行目标文件由多个不同模块的构成,所以在生成单个模块的机器语言目标文件的时候,不可能确定每条指令或每个数据的最终地址,因此,通常把汇编生成的机器语言目标代码称为可重定位的目标文件

啥是可重定位?

假如有两个文件如下:

// main.c
#include <stdio.h>
void add(int, int);
int main() {
    add(10, 20);
    return 0;
}
// func.c
void add(int x, int y) {
    return x+y;
}

首先要记住的的是,在汇编过程中是对每一个文件单独进行。生成单个文件的可重定位的目标文件

注意!是单个文件!

我们使用gcc -c main.s -o main.o 的时候很显然有一个 add() 函数只被声明没有被定义。不知道 add() 的内容。更不知道 add() 的地址。而在汇编代码中我们必须知道调用函数的地址。而在生成的可重定位目标文件中,总不能把调用函数的地址空着吧?需要填一个虚假地址,在链接以后,将多个可重定位目标文件合并在一起,才有可能知道 add() 的真正位置。

这就是重定位。你们懂了吗?

链接

其实链接就是可执行目标文件的生成

啥是可执行目标文件?

就是 CPU 可以直接放入内存了,可以执行了。没有那些虚假地址了。链接主要分为两步,我尽量把这两步说清楚,如果觉得不错,就给我点个喜欢吧。

点个喜欢呗
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。