c语言程序的编译过程

操作系统:ubantu
工具gcc
文件:test.c

abner@DESKTOP-M6D2HEN:~/mytest$ cat test.c
#include

#define MAXC 3

#define MAXB MAXC + 1

#define MAXA MAXB + 2

int main()
{
        int a = MAXA;
        return 0;
}

主要为四个阶段

预处理->编译->汇编->连接

C语言编译过程分成四个步骤:
1,由.c文件到.i文件,这个过程叫预处理
2,由.i文件到.s文件,这个过程叫编译
3,由.s文件到.o文件,这个过程叫汇编
4,由.o文件到可执行文件,这个过程叫链接

当然一般不会单独生成.i .s中间文件。也不会一步步进行c代码的编译

预处理

(1)将所有的#define删除,并且展开所有的宏定义。说白了就是字符替换
(2)处理所有的条件编译指令,#ifdef #ifndef #endif等,就是带#的那些
(3)处理#include,将#include指向的文件插入到该行处,展开头文件
(4)删除所有注释
(5)添加行号和文件标示,这样的在调试和编译出错的时候才知道是是哪个文件的哪一行
(6)保留#pragma编译器指令:其他以#开拓的都是预编译指令,但是这个指令例外,此为编译器指示字,所以此步骤需要保留,关于此指示字的具体用法,在后面的内容将会详细讲解。

预处理阶段其实就是将源文件进行完全展开,删除不必要的项,增加必要的项。

abner@DESKTOP-M6D2HEN:~/mytest$ gcc -E test.c -o test.i
abner@DESKTOP-M6D2HEN:~/mytest$ ll
total 32
drwxrwxrwx 1 abner abner  4096 Feb  2 01:58 ./
drwxr-xr-x 1 abner abner  4096 Jan 31 23:07 ../
-rw-r--r-- 1 abner abner   122 Jan 31 23:07 test.c
-rw-r--r-- 1 abner abner 17929 Feb  2 01:58 test.i

c语言程序的编译过程_第1张图片

编译

编译过程一般包含:
(1)词法分析
(2)语法分析
(3)语义分析
(4)源代码优化
(5)目标代码生成
(6)目标代码优化

编译就是将 高级语言 翻译为 汇编语言的过程。并且在该过程中相关优化代码。

abner@DESKTOP-M6D2HEN:~/mytest$ gcc -S test.i -o test.s
abner@DESKTOP-M6D2HEN:~/mytest$ ll
total 32
drwxrwxrwx 1 abner abner  4096 Feb  2 02:00 ./
drwxr-xr-x 1 abner abner  4096 Jan 31 23:07 ../
-rw-r--r-- 1 abner abner   122 Jan 31 23:07 test.c
-rw-r--r-- 1 abner abner 17929 Feb  2 01:58 test.i
-rw-r--r-- 1 abner abner   386 Feb  2 02:01 test.s

c语言程序的编译过程_第2张图片

汇编

汇编将 汇编语言 转变成 机器语言,生成目标文件
每一个汇编语句几乎都对应一条机器指令。根据汇编指令和机器指令的对照表一一翻译即可。

目标文件由段组成。通常一个目标文件中至少有两个段:
代码段  该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。
数据段  主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。

abner@DESKTOP-M6D2HEN:~/mytest$ gcc -c test.s -o test.o
abner@DESKTOP-M6D2HEN:~/mytest$ ll
total 36
drwxrwxrwx 1 abner abner  4096 Feb  2 02:02 ./
drwxr-xr-x 1 abner abner  4096 Jan 31 23:07 ../
-rw-r--r-- 1 abner abner   122 Jan 31 23:07 test.c
-rw-r--r-- 1 abner abner 17929 Feb  2 01:58 test.i
-rw-r--r-- 1 abner abner  1232 Feb  2 02:02 test.o
-rw-r--r-- 1 abner abner   386 Feb  2 02:01 test.s

c语言程序的编译过程_第3张图片
可以看到内存分布的一些信息,代码段,数据段,bss段。堆栈是在程序的运行过程中。

连接

最后的连接阶段,将所有的 目标文件 和 需要的库连接,生成可执行文件。
链接分为静态链接和动态链接。

abner@DESKTOP-M6D2HEN:~/mytest$ gcc test.o -o test
abner@DESKTOP-M6D2HEN:~/mytest$ ll
total 44
drwxrwxrwx 1 abner abner  4096 Feb  2 02:07 ./
drwxr-xr-x 1 abner abner  4096 Jan 31 23:07 ../
-rwxr-xr-x 1 abner abner  8168 Feb  2 02:07 test*
-rw-r--r-- 1 abner abner   122 Jan 31 23:07 test.c
-rw-r--r-- 1 abner abner 17929 Feb  2 01:58 test.i
-rw-r--r-- 1 abner abner  1232 Feb  2 02:02 test.o
-rw-r--r-- 1 abner abner   386 Feb  2 02:01 test.s

参考:
https://blog.csdn.net/qq_26079093/article/details/93037468
https://blog.csdn.net/s226916240/article/details/102975171
https://blog.csdn.net/chengdanna/article/details/70767329
http://www.ha97.com/2830.html

你可能感兴趣的:(C语言)