程序员的自我修养,最开始看这本书是在学校的图书馆,当时翻了几下,发现这本书内容还真挺特别的。是浙大几个老师写的,就更感觉亲切了,所以自己买了一本书来看看,这也是我到研究生之后买的第一本书了,哈哈,平时都是pdf啥的,其实pdf真不好看。
言归真正,讲讲昨天看到的
从一个HelloWorld程序开始讲起
#include<stdio.h> int main() { printf("helloworld") return 0; }
从高级语言到操作系统可以执行的语言,这里有几个步骤1)预编译 2)编译 3)汇编 4)链接
1)预编译
主要做以下几个事情: 将宏指令展开,#define 展开到全文,比如将#include指令展开,这是递归进行的; 将条件预编译展开,比如#if #ifdef #else之类的 ; 删除所有注释;加入行号,文件名,主要是在编译错误警告时候显示;保留所有#pragma指令;
2)编译
将源代码编译成汇编代码,源代码==>>汇编文件
编译有一个工具,就是ccl(c语言),cclplus(C++语言),jcl(java)。gcc只是这些后台程序的包装,它会根据不同的语言,选择编译程序ccl,汇编器as,连接器ld
3)汇编
汇编是把汇编文件按照汇编指令和机器指令一一对应的关系,把汇编文件会变成目标文件。汇编文件==>>目标文件,这一步由汇编器as来完成
4)链接
链接文件是指把目标文件和静态类型结合起来链接起来形成可执行文件,(链接文件,静态文件)==>可执行文件。
这就是一个程序从源文件到可执行文件的四个步骤。
对于第二步,编译是怎么做的呢?我们详细讨论一下第二点
a,首先是将源代码扫描成Token(把一个语句分隔成若干个Token)
b,然后将Token形成语法树(Syntax Tree)(以表达式为节点的树)
c,然后将语法书分析标记,给每一个结点一个记号,然后形成标有语义的语法数目
d, 中间代码生成,将语法分析树转换成中间代码,形成三地址码语言,在三地址代码语言层面上做一个优化,比如t1=2+6;t2=index+4;t3=t2*t1;array[index]=t3;
在三地址代码做如下转换: t2=index+4;t2=t2*8;array[index]=t2;(中间代码把编译过程分成前端和后端,前端和平台无关,后台与平台有关)
e,目标代码生产和优化
这里主要目标代码生成和目标代码优化
movl index,%ecx;add $4,%ecx;mul $8,%ecx;mobl infdex,%ecx;mov %ecx,array(,eax,4)
对上面目标代码进行优化;
以上这五步就完成了编译的第二步,形成了汇编语言。