7.1 编译器驱动程序

考虑下面的C语言程序,他将作为贯穿本章的一个小的运行示例,帮助我们说明关于链接器是如何工作的一些重要知识点。

----------------------------code/link/main.c
int sum(int *a, int n);
int array[2] = {1,2};
int main()
{
    int val = sum(array,2);
    return val;
}
----------------------------code/link/main.c

a) main.c

----------------------------code/link/sum.c
int sum(int *a, int n)
{
    int i, a = 0;
    for (i = 0 ; i < n ; i ++ ){
        a += a[i];
    }
    return a;
}
---------------------------code/link/sum.c

b) sum.c

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

大多数编译系统提供编译器驱动程序(Complier driver),它代表用户在需要时调用语言预处理器,编译器,汇编器和链接器。比如要用到GNU编译系统构造示例程序,我们就要通过在shall中输入下列命令来调用GCC驱动程序:
linux>gcc -Og -o prog main.c sum.c

这里写图片描述

如上图所示,概括了驱动程序在将示例程序从ASCII码源文件翻译成可执行目标文件时的行为。(如果你想看看这些步骤,用-v选项来运行GCC)驱动程序首先运行C预处理器(cpp),它将C的源程序main.c翻译成一个ASCII码的中间文件main.i:
cpp [other arguments] main.c /tmp/main.i
接下来,驱动程序运行C编译器(CCL),他将main.i翻译成一个ASCII汇编语言文件main.s:
ccl /tmp/main.i -Og [other arguments] -o /tmp/main.s
然后,驱动程序运行汇编器(as),它将main.s翻译成一个可重定位目标文件(relocatable object file)main.o:
as [other arguments] -o /tmp/main.o /tmp/main.s
驱动程序经过相同的过程生成sum.o。最后,它运行链接器程序ld,将main.o和sum.o以及一些必要的系统目标文件组合起来,创建一个可执行目标文件(executable object file)prog。
ld -o prog [system object files and args] /tmp/main.o /tmp/sum.o
要运行可执行文件prog,我们在linux shell的命令行上输入它的名字:
linux > ./prog
shell调用操作系统中一个叫做加载器(loader)的函数,他将可执行文件prog中的代码和数据复制到内存,然后将控制转移到这个程序的开头。

猜你喜欢

转载自blog.csdn.net/xiaohaopei/article/details/82343490
7.1