编译和链接到底隐藏着什么?

一、预编译的花招

首先对在编译器下写好的文件hello.c进行如下指令

$gcc -E hello.c -o hello.i

-E 表示只进行预编译,这时候.c 文件全然已经变成.i 文件了。

我们需要了解的是,在这个过程中,预编译究竟耍了哪些花招。
若打开这个.i 文件,你将会发现:

1.1 所有的#define被删除,并且展开所有的宏定义

比如宏定义常量就会被换成切确的值,定义的字符也会被替换为原来的样子。

1.2 处理所有的预编译指令

比如:#if、#ifdef、#endif之类的。

1.3 #include包含的文件插入到.i 文件中

比如#include<stdio.h>中含有的文件内容会原封不动地放到.i 文件中。

1.4 删除所有注释或者批注

1.5 添加行号和文件名标识

这样做的目的是为了报错的时候信息能够准确指出相应的位置,是个相当人性化的设计,我愿称其为人类高质量程序员的发明。

二、编译才是大佬

对上述预编译完成的文件进行编译,即进行词法分析语法分析语义分析符号汇总后,可以得到汇编文件
但是上述四个步骤需要学习编译原理相关知识,对此我想对现在想用废话富有逻辑性的文字来凑字数的我(还没学过)说:“未来可期”。

相关指令:

$gcc -S hello.i -o hello.s

当然,如果你想直接一步就为,不去预编译:

$gcc -S hello.c -o hello.s

总的来说,编译做的事情最多而且最复杂,是个真正的大佬。

三、汇编是建设基层的好干部

汇编器是将汇编代码转化为机器能够读懂的机器指令和二进制代码。
没有复杂的语法,也没有语义,而且无需指令优化,做最底层的工作,但是尤为重要,是这一步才能让机器听懂人话。

指令:

$gcc -c hello.s -o hello.o

最终让.s 文件变成.o 文件。

四、看似多余的链接

可能你会有这样的疑惑:为什么编译器在编译的时候不直接输出一个可执行文件而是生成一个目标文件,这样啰嗦的操作究竟是为何?
其实,链接会把多个目标文件连接库进行链接,从而生成最终的可执行文件。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值