001

001.在hello world中编译器工具链分别做了什么

为便于理解底层原理,本文中所有操作均在cmd中使用gcc实现

一、预处理器(gcc -E -o a.i a.c)

预处理的分类(以#开头)

  1. 包含头文件
    #include

  2. 宏定义(替换)
    'define 宏名 宏体'

    'define ABC 10'(将ABC替换为10)

    想要得到一个仅被预处理的文件,我们可以在文件所在目录下打开命令行,输入'gcc -E -o a.i a.c'
    这里的-E是指仅进行预处理操作,-o指将a.c的操作结果写入a.i,可知预编译文件后缀为i

  3. 条件编译

    #ifdef DEBUG
    	printf("hello world!\n");
    #endif
    

    根据是否定义DEBUG,我们可以决定是否编译printf,尽管我们可以在预处理的部分直接定义DEBUG,但这样会更改他人的代码,

    这是不合适的。

    我们可以在cmd中手动打开:gcc -DDEBUG -o build a.c (build为exe文件)

二、编译器(gcc -S -o a.s a.i) 汇编器(gcc -c -o a.o a.s)

gcc是十分智能的,我们这里对整个编译过程进行分解,但如果我们输入gcc -c -o a.o a.c,gcc会自动帮我们完成预处理和编译工作。

这里我们主要理解产生可执行文件的过程:

人 --- 编译 --- 汇编语言

汇编语言 --- 汇编 --- 机器指令集

机器指令集 --- 链接 确定数据的地址 --- 可执行文件

下面我们来看链接器

三、链接器 (gcc -o build.exe a.o)

链接器主要用于确定数据的地址,链接过程常见的错误就是一些需要使用的数据我们并没有定义,或者一些调用的函数我们没有去定义,链接器就会报错。

posted on 2025-10-02 00:57  Khalilll  阅读(12)  评论(0)    收藏  举报