深度解析编程语言:从机器语言到高级语言

发表时间: 2017-10-08 09:44

1 机器语言

所有机器都有一张操作命令清单,让你可以控制它。有时这个清单非常简短。电水壶就只允许两种操作:打开和关闭。CD播放器稍微复杂点,除了打开和关闭以外,还能调节音量、播放、暂停、快进、快退、随机播放等。

计算机和其他机器一样,也有一张操作命令清单。比如,可以命令计算机把两个数相加。这种操作命令的总和就是计算机的机器语言(machine language)。

机器语言(machine language)是机器指令的一个列表,其中的每个指令都能直接被处理器理解。它也可以理解成机器指令的一个执行序列。

低层次编程语言(low-level)是抽象程序较低的编程语言。它允许使用一些直接控制硬件的简单命令,比如机器语言就是一种低层次编程语言。

2 汇编语言

计算机刚发明的时候,所有程序就是一条条机器语言的命令。没过多久,程序就改成使用汇编语言了,它要比机器语言写起来稍微方便一点。命令清单还是一样的,就是每个命令换了一个更人性化的名字。机器语言的加法命令是11001101,这可能就是计算机内部的加法表达方式,但是在汇编语言中,这条命令就改成了add。

机器语言笔与汇编语言的共同问题就是,只能让大多数计算机做一些很简单的事情。比如,假定你想让计算机的蜂鸣器响10次,但是不存在一条直接的机器语言命令让电脑重复进行n次操作,所以只能用机器语言写出下面这样的程序:

a

将数字10存入内存地址0;

如果内存地址0的值为负数,跳到b行;

蜂鸣器发出声音;

将内存地址0的值减1;

跳到a行;

b

…程序的其他部分…

如果只是为了让蜂鸣器响10次就不得不写这么多代码,不难想象写出一个文字处理器或电子表格将是一项多么浩大的工程。

顺便说一句,请再看一下上面的程序。蜂鸣器真的会响10次吗?不,响了11次。我不应该在第一行使用10,而应该使用9。我故意在这个例子中留了一个bug,证明编程语言的一个重要特点:一个操作所需的代码越多,就越难避免bug,也越难发现它们。

3 高级语言

现在假设你不得不用汇编语言开发程序,但是你有了一个助手,他可以帮你承担那些麻烦的脏活。所以,你只要把程序写成下面这样就行了:

Dotimes 10 蜂鸣器响

接下来,你的助手会用汇编语言来实现这条命令(假定他不会产生bug)。

事实上大多数程序员就是这样工作的,不同之处就是,程序员的助手不是一个人,而是编译器。所谓“编译器”,本身就是一个程序,作用是将简便方式书写的程序(就像上面这一行命令)转变为硬件可以理解的语言。

这种简便方式书写的程序所使用的语言就叫做高级语言。它让你能够使用命令开发程序,比如现在你就有了“重复n次操作”的命令,不再仅限于只能做简单的“两个数相加”。

写程序时有了方便的命令,就可以把程序写得更简短。在上面假想的例子中,高级语言写出来的程序的长度只有机器语言的五分之一。所以,要是你犯错了,现在也更容易发现。

高级语言还有一个优点,它使得程序更具有可移植性。不同计算机的机器语言都不完全相同的。所以,你无法将为某一机型写的机器语言程序放到另一机型上运行,只有彻底重写才能实现。但是,如果你的程序是用高级语言写的,你只需要重写编译器就可以了。

编译器不是高级语言唯一的实现方法,另一种方法是使用解释器,它的作用是实时地将代码解释为相应的机器语言,然后一行一行地运行。相比之下,编译器则是先将整个程序全部翻译成机器语言,然后再运行。

编程语言就是编译器的输入,然后被转成目标码进行输出的东西。从20世纪80年代开始,硬件的指令集都是针对编译器而不是针对程序员设计的。

现在的高级语言大概有几百种之多。不同机器语言的指令集基本相同,但是高级语言就不一样,它们开发程序的模式差别相当大。

高级语言是比机器语言抽象得多的语言。抽象(abstract),主要功能在于隐藏细节,编程语言越抽象,你写出程序所需的运算步骤就越少,每一步的功能就越强。

一种好的编程语言通常要求具备的条件:

I 免费

II 一本好的相关书籍

III 要有在线文档

IV 语言要简洁

简洁性的特点是要求语言更抽象,能够用较少的字符表达相同的功能。能够以更少、更短的语法单位表达出来。

简洁性的最高形式就是有别人帮你写好的功能模块,你只要调用就可以了,别人帮你写好的这种程序就是函数库(函数库(library)是已经写好的代码片段,可以用来执行特定任务。)。

这种语言干净简练,具有最高层次的抽象和互动性,而且很容易装备,可以只用很少的代码就解决常见的问题。

优秀的编程语言应该是用来帮助思考程序的,而不是用来表达你已经想好的程序。

技术的变化速度通常是很快的。但是,编程语言不一样,与其说它是技术,还不如说是程序员的思考模式。编程语言是技术和宗教的混合物。