操作系统:ubantu
工具gcc
文件:test.c
abner@DESKTOP-M6D2HEN:~/mytest$ cat test.c
#include<stdio.h>
#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
编译
编译过程一般包含:
(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
汇编
汇编将
汇编语言
转变成
机器语言
,生成
目标文件
。
每一个汇编语句几乎都对应一条机器指令。根据汇编指令和机器指令的对照表一一翻译即可。
目标文件由段组成。通常一个目标文件中至少有两个段:
代码段 该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。
数据段 主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。
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
可以看到内存分布的一些信息,代码段,数据段,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