# 7.1 编译器驱动程序

考虑图 7-1 中的 C 语言程序。它将作为贯穿本章的一个小的运行示例，帮助我们说明关于链接是如何工作的一些重要知识点。

{% tabs %}
{% tab title="code/link/main.c" %}

```c
int sum(int *a, int n);

int array[2] = {1, 2};

int main()
{
    int val = sum(array, 2);
    return val;
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="code/link/sum.c" %}

```c
int sum(int *a, int n)
{
    int i, s = 0;
    
    for (i = 0; i < n; i++) {
        s += a[i];
    }
    return s;
}
```

{% endtab %}
{% endtabs %}

> 图 7-1 示例程序 1。这个示例程序由两个源文件组成，main.c 和 sum.c。main 函数初始化一个整数数组，然后调用 sum 函数来对数组元素求和

大多数编译系统提供编译器驱动程序（compiler driver），它代表用户在需要时调用语言预处理器、编译器、汇编器和链接器。比如，要用 GNU 编译系统构造示例程序，我们就要通过在 shell 中输入下列命令来调用 GCC 驱动程序：

```c
linux> gcc -Og -o prog main.c sum.c
```

图 7-2 概括了驱动程序在将示例程序从 ASCII 码源文件翻译成可执行目标文件时的行为。（如果你想看看这些步骤，用 **-v** 选项来运行 GCC。）驱动程序首先运行 ✦C 预处理器（cpp）✦，它将 C 的源程序 main.c 翻译成一个 ASCII 码的中间文件 main.i：

```c
cpp [other arguments] main.c /tmp/main.i
```

{% hint style="info" %}
✦C 预处理器（cpp）✦：在某些 GCC 版本中，预处理器被集成到编译器驱动程序中。
{% endhint %}

![图 7-2 静态链接。链接器将可重定位目标文件组合起来，形成一个可执行目标文件 prog](/files/-MI8oSBe7kBcpszDCC7T)

接下来，驱动程序运行 C 编译器（cc1），它将 main.i 翻译成一个 ASCII 汇编语言文件 main.s：&#x20;

```c
cc1 /tmp/main.i -Og [other arguments] -o /tmp/main.s
```

然后，驱动程序运行汇编器（as），它将 main.s 翻译成一个**可重定位目标文件**（relocatable object file）main.o：

```c
as [other arguments] -o /tmp/main.o /tmp/main.s
```

驱动程序经过相同的过程生成 sum.o。最后，它运行链接器程序 ld，将 main.o 和 sum.o 以及一些必要的系统目标文件组合起来，创建一个**可执行目标文件**（executable object file）prog：

```c
ld -o prog [system object files and args] /tmp/main.o /tmp/sum.o
```

要运行可执行文件 prog，我们在 Linux shell 的命令行上输入它的名字：

```c
linux> ./prog
```

shell 调用操作系统中一个叫做**加载器**（loader）的函数，它将可执行文件 prog 中的代码和数据复制到内存，然后将控制转移到这个程序的开头。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hansimov.gitbook.io/csapp/part2/ch07-linking/7.1-compiler-drviers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
