IDE中的构建(build) 包含了编译和链接.
2.1被隐藏了的过程
预处理,编译,汇编,链接 ESc iso
2.2编译器做了什么
6步:扫描,语法分析,语义分析,源代码优化,代码生成,目标代码优化
1词法分析:
源代码可被输入到扫描器(scanner),把源代码非空字符分割成一系列记号(token),
具体而言是lex程序实现词法扫描.
2语法分析:
对扫描器产生的记号进行语法分析,从而产生语法树(Syntax Tree).
此树以表达式(赋值=,加法+,数组,括号)为节点单位.(即以各种符号和数字等为节点的树)
通常叶子节点就是字符串和数字.树定下来则优先级也定下来了
具体而言是yacc(yet another compiler compiler)程序实现此功能
对于不同语言,编译器开发者只需改变语法规则,而无需编写语法分析器
3语义分析:
有语义分析器(Semantic Analyzer)完成.语法上指针可以和浮点数相乘,但语义上这是不合法的
编译器所分析的语义是静态语义(Static Semantic)(即在编译期间可确定的语义)
静态语义分析包括声明和类型匹配,类型的转换.float-->int可以转换 float-->指针不合法
经过语义分析后,语法树的表达式都被标识了类型
4中间语言生成:
有源代码优化器(source code optimizer)
......
5目标代码生成与优化
......
问题引出:当目标代码中有变量定义在其他模块(编译单元)该怎么办.
其实得通过链接器确定地址,才能链接成可执行文件
2.3链接器的年龄比编译器长
原始的存储介质是纸带,跳到一个绝对地址执行时,要经过计算才能确定此地址,这种技术(重定位)
非常麻烦.(黑暗程序员)
有了汇编指令后(jump指令)才有改进
在各个程序被分割成多个模块后,这些模块间如何这成一个单一的程序呢?
即(模块间如何通信:1模块间的函数调用2模块间的变量访问).
函数访问得知目标变量的地址.确定此地址的技术就是链接
2.4模块拼装--静态链接
链接就是把各模块间相互引用的部分都处理好,使各模块间正确的衔接.
和暗黑程序员人工调整跳到某个地址一样
我们最常用的库是运行时库(Runtime Library),也就是说编译出目标文件(.o文件)后,要链接一些库最后生成可执行文件
main.c 调用fun.c中的foo(). mian先编译,搁置foo()的地址.链接时,链接器确定此地址(重定位)
具体参考51单片机