本节书摘来自华章计算机《编译与反编译技术实战》一书中的第2章,第2.1节,作者 刘晓楠 陶红伟 岳峰 戴超,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
第2章
编译器实践概述
人与计算机之间的交流也是通过语言进行的,但人类能理解的语言与机器可以理解的语言是不同的,中间需要翻译,因此,相应的编译器诞生了。编译技术所讨论的问题就是如何把符合人类思维方式的意愿(即源程序)翻译成计算机能够理解和执行的形式(即目标程序),而实现从源程序到目标程序转换的程序被称为编译程序或编译器。最早的编译器是20世纪50年代后期的Fortran编译器,该编译器也为后续高级语言和编译器的涌现奠定了基础。与编译技术相反,反编译技术所讨论的问题就是如何把计算机能够理解和执行的形式(目标程序)翻译成符合人类便于理解的形式(源程序或流程图),实现从目标程序到便于人类理解的系列文档的转换程序被称为反编译程序或反编译器。反编译技术起源于20世纪60年代,虽然在时间上只比编译技术晚10年左右,但反编译技术的成熟度却远不如编译技术。半个世纪以来,也涌现了不少实验性的反编译器,如Dcc、Boomerang和IDA的反编译插件Hex_rays等。但这些反编译器都有这样或那样的缺陷,还不能像编译器那样强健。
本章仅对编译器实践方面的知识进行简要阐述,反编译实践方面的概要介绍将在后续章节给出。
2.1 编译器、解释器及其工作方式
就目前计算机的硬件发展水平而言,硬件只能识别由0、1字符串组成的机器指令序列,即机器指令程序或目标程序。在计算机发明的早期,计算机只能按照输入的机器指令程序进行简单的计算。但是,机器指令程序不易被人类理解,用它编写程序不仅困难而且还容易出错。于是后来就引入了代替0、1字符串的由助记符号表示的指令,即汇编指令,汇编指令的集合被称为汇编语言,汇编指令序列被称为汇编语言程序。汇编程序实际上与机器语言程序是一一对应的,都要求程序员按照指令工作的方式来思考和解决相关问题,也就是说,两者之间并无本质区别。因此,它们都被称为面向机器的语言或低级语言,以此与更高级的语言相区别,当然,早期并不知道高级别的语言是否能设计和实现。
计算机的发展和普及超乎人们的想象,应用需求的大量增长导致程序员的需求也大幅增长,但是,能够用机器语言或汇编语言编程的人员数量却不多,满足不了这种需求;同时,许多不同领域的科技工作者也想自己动手编写程序来直接解决问题。因此,抽象度更高、功能更强的语言来作为程序设计语言就成为必然,于是就产生了面向各类应用的便于人类理解与运用的程序设计语言,即高级语言。尽管人类可以借助高级语言来编写程序,但计算机硬件真正能够识别和理解的语言还是0、1组成的机器语言,这就需要在高级语言与机器语言之间建立转换系统,使得高级语言能够自动转换为机器语言。也就是说需要若干“翻译”,把各类高级语言翻译成机器语言。程序设计语言通常被分成三个层次:高级语言、汇编语言、机器语言。高级语言可以翻译成机器语言,也可以翻译成汇编语言,这两种翻译都被称为编译。汇编语言到机器语言的翻译称为汇编。编译和汇编属于正向工程,有时还需要将机器语言翻译成汇编语言或高级语言,这通常被称为反汇编或反编译,属于逆向工程范畴。
高级语言的工作方式有两种,一种是编译器工作方式,另一种是解释器工作方式。
在编译器工作方式下,源程序的翻译和翻译后程序的运行处于两个相互独立的阶段。用户输入源程序,编译器对该源程序进行编译,生成目标程序,这个阶段称为编译阶段。目标程序在适当的输入下执行,最终得到运行结果的过程称为运行阶段。
解释器是另一种形式的翻译器。它把翻译和运行结合在一起进行,边翻译源程序,边执行翻译结果,而这种工作方式被称为解释器工作方式。
形象地说,编译器的工作相当于翻译一本原著,原著与源程序对应,译著与目标程序对应,计算机的运行相当于阅读一本译著,这时,原著和翻译人员并不需要在场,译著是主角。解释器的工作相当于在进行现场翻译,外宾和翻译都要在场,翻译一边听外宾讲话,一边翻译给听众,翻译是听众关注的主角。解释器与编译器的最本质区别是:运行目标程序时的控制权在解释器而不是目标程序,也就是说,运行的是解释器,目标程序是解释器的输入。