程序员自我修养笔记
空闲时间想读本书,偶然看到了《程序员的自我修养》(俞甲子/石凡/潘爱民著)一书,看书名并不引以为然,但是看了下书的目录,太惊讶了,国内本土竟然还有这厉害的书,就好像当初我看《鸟哥的私房菜》的书名,感觉并不咋地,后来带我入linux大坑的,就是我曾经不以为然的东西。
注:鸟哥私房菜,linux入门必备。
正如序言所说,这本书修炼的是内功,修炼的是《易筋经》,看了这书,对你涨薪,或者找工作可能并不会带来很大帮助(比较深的可能还是有用的,比如逆向安全方面),但是对你以后理解学习会有很大的提高,特别是接触到相对底层的一些东西。
简单做下总结
一、程序的编译链接过程简述
1.1 预处理
预编译过程主要处理那些源代码文件中的以“#”开始的预编译指令。比如“#include”、“#define”等,主要处理规则如下:
• 将所有的“#define”删除,并且展开所有的宏定义。
• 处理所有条件预编译指令,比如“#if”、“#ifdef”、“#elif”、“#else”、“#endif”。
• 处理“#include”预编译指令,将被包含的文件插入到该预编译指令的位置。注意,这个过程是递归进行的,也就是说被包含的文件可能还包含其他文件。
• 删除所有的注释“//”和“/ /”。
• 添加行号和文件名标识,比如#2“hello.c”2,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号。
•保留所有的#pragma编译器指令,因为编译器须要使用它们。
1.2 编译
编译过程一般可以分为6步:扫描、语法分析、语义分析、源代码优化、代码生成和目标代码优化。
1.2.1 词法分析
首先源代码程序被输入到扫描器(Scanner),扫描器的任务很简单,它只是简单地进行词法分析,运用一种类似于有限状态机(Finite State Ma-chine)的算法可以很轻松地将源代码的字符序列分割成一系列的记号(Token)。(注:lex 可用于做词法分析)
1.2.2 语法分析
接下来语法分析器(Grammar Parser)将对由扫描器产生的记号进行语法分析,从而产生语法树(Syntax Tree)。整个分析过程采用了上下文无关语法(Context-free Grammar)的分析手段,如果你对上下文无关语法及下推自动机很熟悉,那么应该很好理解。(注:语法分析可用yacc来做)
1.2.3 语义分析
语法分析仅仅是完成了对表达式的语法层面的分析,但是它并不了解这个语句是否真正有意义。编译器所能分析的语义是静态语义(Static Semantic),所谓静态语义是指在编译期可以确定的语义。
(注:就是比如说有这样语义 char p = NULL; p = “hello world”, 语义上没问题,但是运行会崩溃,也有不崩溃的情况,在允许对0地址操作的情况下,这里 多说两句,自然语言的处理在最初是采用以上方式来进行的,但是对某些语义根本没有解决方案,现在的自然语言处理改用了统计学的方式,详见 吴军《数学之美》)
1.2.4 源代码优化
现代的编译器有着很多层次的优化,往往在源代码级别会有一个优化过程。我们这里所描述的源码级优化器(Source Code Optimizer)
其实直接在语法树上作优化比较困难,所以源代码优化器往往将整个语法树转换成中间代码(Intermedi-ate Code),它是语法树的顺序表示,其实它已经非常接近目标代码了。
中间代码使得编译器可以被分为前端和后端。编译器前端负责产生机器无关的中间代码,编译器后端将中间代码转换成目标机器代码。这样对于一些可以跨平台的编译器而言,它们可以针对不同的平台使用同一个前端和针对不同机器平台的数个后端。
int a = 1;
int b = a + 2;
//优化后
int b = 3;
1.2.5 代码生成
源代码级优化器产生中间代码标志着下面的过程都属于编译器后端。编译器后端主要包括代码生成器(Code Generator)和目标代码优化器(Tar-get Code Optimizer)。
代码生成器将中间代码转换成目标机器代码。
1.2.6 目标代码优化
目标代码优化器对上述的目标代码进行优化,比如选择合适的寻址方式、使用位移来代替乘法运算、删除多余的指令等。
1.3 汇编
汇编器是将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令。所以汇编器的汇编过程相对于编译器来讲比较简单,它没有复杂的语法,也没有语义,也不需要做指令优化,只是根据汇编指令和机器指令的对照表一一翻译就可以了,“汇编”这个名字也来源于此。
1.4 链接
静态链接
二、ELF文件格式
现在PC平台流行的可执行文件格式(Exe-cutable)主要是Windows下的PE(Portable Exe-cutable)和Linux的ELF(Executable LinkableFormat),它们都是COFF(Common file format)格式的变种。
.text段:执行语句,也就是函数代码
.data段:已经初始化的全局变量与局部静态变量
.bbs 段:未初始化的全局变量和局部静态变量
注:bbs段只是预留位置,并不占用elf文件的空间
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 68813175@qq.com