C/C++|物联网开发入门+项目实战|C语言基础|C语言的预处理及编译过程分析-学习笔记(2)

文章详细分析了C语言从预处理(宏替换和包含文件处理)到编译(cc1.exe转换为汇编代码)、汇编(as.exe生成目标文件.o)以及链接(collect2.exe整合.o文件和系统库,生成可执行文件)的完整过程。通过gcc命令的不同参数如-E,-S,-c,-o展示了各个阶段的输出结果。
摘要由CSDN通过智能技术生成


摘自: 麦子学院-C语言程序设计及快速入门

C语言的预处理及编译过程分析

gcc -v -o build 1.c

输出内容

C:\Users\Vera\Desktop>gcc -v -o build 1.c
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../libexec/gcc/x86_64-w64-mingw32/4.7.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../build/gcc/src/configure --target=x86_64-w64-mingw32 --prefix=/c/bb/vista64-mingw32/mingw-x86-x86_64/build/build/root --with-sysroot=/c/bb/vista64-mingw32/mingw-x86-x86_64/build/build/root --enable-languages=all,obj-c++ --enable-fully-dynamic-string --disable-multilib
Thread model: win32
gcc version 4.7.0 20111220 (experimental) (GCC)
COLLECT_GCC_OPTIONS='-v' '-o' 'build.exe' '-mtune=generic' '-march=x86-64'
 f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../libexec/gcc/x86_64-w64-mingw32/4.7.0/cc1.exe -quiet -v -iprefix f:\anaconda3\pkgs\mingw-4.7-1\mingw\bin\../lib/gcc/x86_64-w64-mingw32/4.7.0/ -U_REENTRANT 1.c -quiet -dumpbase 1.c -mtune=generic -march=x86-64 -auxbase 1 -version -o C:\Users\Vera\AppData\Local\Temp\ccRFZVtk.s
GNU C (GCC) version 4.7.0 20111220 (experimental) (x86_64-w64-mingw32)
        compiled by GNU C version 4.5.2, GMP version 5.0.1, MPFR version 2.4.2, MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
ignoring duplicate directory "f:/anaconda3/pkgs/mingw-4.7-1/mingw/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/4.7.0/include"
ignoring nonexistent directory "c:/bb/vista64-mingw32/mingw-x86-x86_64/build/build/rootc:/bb/vista64-mingw32/mingw-x86-x86_64/build/build/root/lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../include"
ignoring duplicate directory "f:/anaconda3/pkgs/mingw-4.7-1/mingw/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/4.7.0/include-fixed"
ignoring duplicate directory "f:/anaconda3/pkgs/mingw-4.7-1/mingw/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include"
ignoring nonexistent directory "c:/bb/vista64-mingw32/mingw-x86-x86_64/build/build/rootc:/mingw/include"
#include "..." search starts here:
#include <...> search starts here:
 f:\anaconda3\pkgs\mingw-4.7-1\mingw\bin\../lib/gcc/x86_64-w64-mingw32/4.7.0/include
 f:\anaconda3\pkgs\mingw-4.7-1\mingw\bin\../lib/gcc/x86_64-w64-mingw32/4.7.0/include-fixed
 f:\anaconda3\pkgs\mingw-4.7-1\mingw\bin\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include
End of search list.
GNU C (GCC) version 4.7.0 20111220 (experimental) (x86_64-w64-mingw32)
        compiled by GNU C version 4.5.2, GMP version 5.0.1, MPFR version 2.4.2, MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 6dafe883c1f59de430b201ea1dfaaae8
COLLECT_GCC_OPTIONS='-v' '-o' 'build.exe' '-mtune=generic' '-march=x86-64'
 f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/bin/as.exe -o C:\Users\Vera\AppData\Local\Temp\ccaZqlwM.o C:\Users\Vera\AppData\Local\Temp\ccRFZVtk.s
COMPILER_PATH=f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../libexec/gcc/x86_64-w64-mingw32/4.7.0/;f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../libexec/gcc/;f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/bin/
LIBRARY_PATH=f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0/;f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/;f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/lib/../lib/;f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'build.exe' '-mtune=generic' '-march=x86-64'
 f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../libexec/gcc/x86_64-w64-mingw32/4.7.0/collect2.exe --sysroot=c:/bb/vista64-mingw32/mingw-x86-x86_64/build/build/root -m i386pep -Bdynamic -o build.exe f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/lib/../lib/crtbegin.o -Lf:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0 -Lf:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc -Lf:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/lib/../lib -Lf:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/lib C:\Users\Vera\AppData\Local\Temp\ccaZqlwM.o -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/lib/../lib/crtend.o

主要步骤

预处理(相当于替换)

cpp -o build.i 1.c 相当于gcc -E -o build.i 1.c

示例

修改1.c,加入define:

C:\Users\Vera\Desktop>type 1.c
#include <stdio.h>
#define POLICE  110
int main()
{
    int a =POLICE;
    printf("hello world! 你好\n");
    return 0;
}

C:\Users\Vera\Desktop>gcc -E -o build.i 1.c
显示build.i的内容

C:\Users\Vera\Desktop>type build.i

输出值:

# 1 "1.c"
# 1 "<command-line>"
# 1 "1.c"
# 1 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/stdio.h" 1 3
# 9 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/stdio.h" 3
# 1 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/_mingw.h" 1 3
# 10 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/_mingw.h" 3
# 1 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/_mingw_mac.h" 1 3
# 32 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/_mingw_mac.h" 3

# 41 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/_mingw_mac.h" 3

# 11 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/_mingw.h" 2 3
# 293 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/_mingw.h" 3
# 1 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/vadefs.h" 1 3
# 13 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/vadefs.h" 3
# 1 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/_mingw.h" 1 3
# 739 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/_mingw.h" 3
# 1 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/sdks/_mingw_directx.h" 1 3
......
# 1025 "f:\\anaconda3\\pkgs\\mingw-4.7-1\\mingw\\bin\\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/stdio.h" 2 3
# 2 "1.c" 2

int main()
{
    int a =110;
    printf("hello world! 你好\n");
    return 0;
}

1、主程序体以上的输出内容是预编译时加入的头文件部分,编译器自动加入;
2、可以看到宏名POLICE已经被110替换了。define,include均在本阶段被执行了,所以本质上将它们都不是关键字(关键字应该由编译器处理)。

编译

第一条调用的命令:f:/anaconda3/pkgs/mingw-4.7-1/mingw/bin/…/libexec/gcc/x86_64-w64-mingw32/4.7.0/cc1.exe … 1.c…-o \ccRFZVtk.s**

cc1.exe称作编译器,相当于gcc -S 1.c ccRFZVtk.s

汇编(让cpu认识代码)

第2条调用的命令:x86_64-w64-mingw32/bin/as.exe …-o \ccaZqlwM.o…\ccRFZVtk.s

上一步的输出文件ccRFZVtk.s作为本次的输入文件,执行as.exe后输出\ccaZqlwM.o文件。
as.exe执行的操作,相当于gcc -c,即先执行编译,再执行汇编,因为不能直接汇编1.c,即-c选项直接生成.o。

链接器(链接系统标准库)

第3条调用的命令:/x86_64-w64-mingw32/4.7.0/collect2.exe -o build.exe 多个.o文件

collect2.exe的操作,相当于gcc -o,已包含了-S,-c的操作。

示例

C:\Users\Vera\Desktop>gcc -S -o build.s 1.c

C:\Users\Vera\Desktop>dir/w
驱动器 C 中的卷是 OS
卷的序列号是 70C8-B66E

C:\Users\Vera\Desktop 的目录

[.] […] 1.c build.s

C:\Users\Vera\Desktop>notepad build.s
这里生成的是x86的汇编代码:

C:\Users\Vera\Desktop>gcc -c -o build.o build.s

C:\Users\Vera\Desktop>dir/w
驱动器 C 中的卷是 OS
卷的序列号是 70C8-B66E

C:\Users\Vera\Desktop 的目录

[.] […] 1.c build.o build.s

C:\Users\Vera\Desktop>notepad build.o
这里生成二进制代码。
C:\Users\Vera\Desktop>gcc -o build 1.c

C:\Users\Vera\Desktop>dir/w
驱动器 C 中的卷是 OS
卷的序列号是 70C8-B66E

C:\Users\Vera\Desktop 的目录

[.] […] 1.c build.exe build.o build.s

C:\Users\Vera\Desktop>build
hello world! 你好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打酱油的工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值