一个c代码编译的四个阶段

原始代码

//test.c
#include <stdio.h>

#define Pi 3.14

void hotPot() {
        printf("I want to eat hot pot!\n");
}

int main() {
        printf("Hello world.\n");

        float a = Pi + 3;

        hotPot();

        return 0;
}

预处理阶段

  • 把头文件编译进去
  • 把宏替换
  • gcc -E test.c -o test.i

代码

// ....前面是编译进来的头文件,省略
# 868 "/usr/include/stdio.h" 3 4

# 2 "test.c" 2




# 5 "test.c"
void hotPot() {
 printf("I want to eat hot pot!\n");
}

int main() {
 printf("Hello world.\n");

 float a = 3.14 + 3;

 hotPot();

 return 0;
}

可以看出来,宏Pi被替换成了3.14。

编译

  • 将前面的代码转换为汇编代码。
  • gcc -S test.i -o test.s
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

汇编

  • 将汇编代码转换为二进制机器码。
  • gcc -c test.s -o test.o

链接

  • 将汇编生成的OBJ文件、系统库的OBJ文件、库文件链接起来,最终生成可执行程序。
  • gcc test.o -o test
    在这里插入图片描述
    最近学习操作系统,有一些关于链接的感想。为什么要有链接的过程。假如模块A调用了模块B,它们分别都有自己的地址空间,但是A不知道B的地址。多个模块和用到的函数库链接起来,排成一个线性的序列,排好之后就知道跳转的地址在哪了。
发布了141 篇原创文章 · 获赞 40 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/m0_37822685/article/details/104343909