PLA 2019-02-25
机器语言(Machine Language)
机器语言是面向机器的语言,每一个由机器语言所编写的程序只适用于某种特定类型的计算机,即指令代码通常随CPU型号的不同而不同。它可以被计算机硬件直接识别,不需要翻译。一句机器语言实际上就是一条机器指令,它由操作码和地址码组成。机器指令的形式是用0、1组成的二进制代码串。
汇编语言(Assemble Language)
汇编语言是一种面向机器的程序设计语言,它是为特定的计算机或计算机系列设计的。汇编语言采用一定的助记符号表示机器语言中指令和数据,即用助记符号代替了二进制形式的机器指令。这种替代使得机器语言“符号化”,所以汇编语言也是符号语言。每条汇编语言的指令就对应了一条机器语言的代码,不同型号的计算机系统一般有不同的汇编语言。
计算机硬件只能识别机器指令,执行机器指令,对于用助记符表示的汇编指令是不能执行的。汇编语言编写的程序要执行的话,必须用一个程序将汇编语言翻译成机器语言程序,用于翻译的程序称为汇编程序(汇编系统)。
汇编程序是将用符号表示的汇编指令码翻译成为与之对应的机器语言指令码。用汇编语言编写的程序称为源程序,变换后得到的机器语言程序称为目标程序。
高级语言
机器语言与汇编语言受机器限制费工费时,并且缺乏通用性,为解决此问题,人们努力创造一种独立于计算机的语言。从20世纪50年代中期开始到20世纪70年代陆续产生了许多高级算法语言。这些算法语言中的数据用十进制来表示,语句用较为接近自然语言的英文字来表示。它们比较接近于人们习惯用的自然语言和数学表达式,因此称为高级语言。高级语言具有较大的通用性,尤其是有些标准版本的高级算法语言,在国际上都是通用的。用高级语言编写的程序能使用在不同的计算机系统上。
但是,对于高级语言编写的程序计算机是不能识别和执行的。要执行高级语言编写的程序,首先要将高级语言编写的程序翻译成计算机能识别和执行的二进制机器指令,然后供计算机执行。
一般将用高级语言编写的程序称为“源程序”,而把由源程序翻译成的机器语言程序或汇编语言程序称为“目标程序”。把用来编写源程序的高级语言或汇编语言称为源语言,而把和目标程序相对应的语言(汇编语言或机器语言)称为目标语言。
计算机将源程序翻译成机器指令时,通常分两种翻译方式:一种为“编译”方式,另一种为“解释”方式。所谓编译方式是把源程序翻译成等价的目标程序,然后再执行此目标程序。而解释方式是把源程序逐句翻译,翻译一句执行一句,边翻译边执行。解释程序不产生将被执行的目标程序,而是借助于解释程序直接执行源程序本身。一般将高级语言程序翻译成汇编语言或机器语言的程序称为编译程序。
一般来讲高级语言和低级语言有一下特点
高级语言:实现效率高,执行效率低,对硬件的可控性弱,目标代码大,可维护性好,可移植性好 低级语言:实现效率低,执行效率高,对硬件的可控性强,目标代码小,可维护性差,可移植性差
我们都知道CPU运行的是二进制指令,所有的语言编写的程序最终都要翻译成二进制代码,但是为什么实现会有以上众多差异呢?下面以C语言为高级语言代表,汇编语言为低级语言代表来解释一下。越低级的语言,形式上越接近机器指令,汇编语言就是与机器指令一一对应的。而越高级的语言,一条语句对应的指令数越多,其中原因就是高级语言对底层操作进行了抽象和封装,使编写程序的过程更符合人类的思维习惯,并且极大了简化了人力劳动。也就是说你用高级语言写一句,会被转换成许多底层操作,大部分的工作交给了负责转换的机器(即编译器),从而人力得到了解放。因为机器就是用来为人类提供便利的,所以说高级语言的出现是计算机发展的必然结果。下面重点解释为何低级语言的执行效率更高:
低级语言可以通过控制硬件访问来优化效率
越低级的语言月接近底层,即控制硬件访问的能力越强,对硬件资源的利用效率越高。比如说汇编语言能够访问寄存器,而C语言就做不到。通过对寄存器等硬件的访问,我们可以将程序的运行效率优化到最大,而像C这样的高级语言用的最多的是堆栈这样的内存结构,访问速度自然不如寄存器了。
高级语言程序存在工作冗余,有效率损失
各种语言需要通过编译器翻译成机器码,不管编译多么智能和强大,都是会产生冗余。这里的冗余不是指指令的多少,而是有没有做没有必要的事情。 产生冗余的多少关键要看语言跟机器指令之间的耦合度。耦合度越大,编译器翻译过程越简单,产生的冗余越少。对应汇编来书,由于与机器码一一对应,所以翻译后基本没有冗余。而高级语言由于进行了抽象和封装,所以与机器指令间的耦合度较低,因此整个翻译过程较复杂,因此在高级语言在具体化的过程中不可避免会产生较多的冗余。据说C语言有10%的效率损失。
效率高不高,还取决于程序员水平
一个差的程序员用汇编写程序,可能存在很多没有用的操作,而程序高手用c语言写,可以将程序优化到最大。最终的结果可能是汇编的程序跑不过C语言程序。
总之,完成一项工作的工作量是不变的,机器做的 多了,人就做的就少了,同时人对程序的很多细节的控制性也减弱了。各种语言都是在这个平衡点附近纠结。从C/C++的注重机器运算效率的优化,到C#/JAVA注重开发效率的优化。人操作起来更加方便了,更高效了,代价就是,机器要处理的东西更多,运算效率被进一步压缩。但是这个压缩在许可范围内,那么这也是一种进步。