本帖最后由 friend0720 于 2016-3-4 23:35 编辑
程序是个啥玩意?
曾经在论坛里看到有人提问:“程序是如何让硬件工作的?”。当时我在想:“这人一定没学过数字电子”。想要说明这个问题,首先要知道程序是怎么来的。下面我用一些简单的例子说说程序到底是个啥玩意,它到底是如何产生和发展的。
1三极管的发明
1906年一个叫德福雷斯特的美国人,在弗莱明发明的二极管(电子管)基础上,发明了三极管,从此人类掌握了打开数字电子世界大门的钥匙。我们知道三极管除了能工作在放大状态,还能工作在导通和截至状态(即0和1的状态)。人们利用三极管这一特性,发明了各种时序电路和逻辑门电路。常见的逻辑门电路有与门、非门、或门、同或门、异或门、与非门等等。
常见逻辑门电路
聪明的灵长类动物将这些逻辑门电路组合起来,从而发明了更复杂的逻辑电路,38译码器就是其中的一种。灵长类动物发明的复杂逻辑电路千千万万,这里之所以只提及38译码器,是因为它逻辑简单,又比较常见,容易讲清楚。
38译码器
2 38译码器
学过数字电子的人都应该知道38译码器,简单讲就是3个脚输入,8个脚输出。
38译码器真值表
从38译码器真值表可以看出,当A[2,0]=000时Y[7,0]=11111110;
3 机器指令
下图是一个使用38译码器的简易电路图,我们暂时不考虑电路图的电器特性,只考虑其逻辑特性。那么我们如何令图中的发光二极管D0点亮呢?很简单,根据真值表,我们只要令A2=0、A1=0、A0=0即可。同理,如果我们令A[2,0]=111,那么发光二极管D7将被点亮。
很显然,想要点亮哪个LED,我们只要在真值表画红圈部分,找到对应的编码输入给A[2,0]即可。我们称真值表中画红圈这部分为38译码器的指令表,也就是说,它们就是38译码器这个逻辑器件的机器指令。
4第一个程序
到这里我们已经可以随心所欲的控制每个LED的亮灭了,那么我们如何让这些LED按照一定的顺序点亮呢?比如让LED从D0到D7依次点亮?我想你会说:“这太简单了”。是的,很简单。我们只要按照真值表中从上到下的顺序,把38译码器的机器指令依次赋值给A[2,0]即可:
000 ;D0亮
001 ;D1亮
010 ;D2亮
011 ;D3亮
100 ;D4亮
101 ;D5亮
110 ;D6亮
111 ;D7亮
恭喜你!世界上第一个程序诞生了,它很简单,很简陋,和你想想中的程序也许完全不是一回事,但它的的确确是一个程序。所谓“程序”,即事务执行的流程和顺序,在这里我们让LED按照我们想要的顺序点亮了,那么上面那些机器指令的组合就是一个不折不扣的程序。
到这里我们已经回答了开篇之初的那个问题。程序是一组有顺序(或有逻辑)的机器指令的组合,机器指令又是一组0和1的组合(即高低电平的组合),而0和1(高低电平)又控制着三极管的导通和关断,三极管是一个电子元件,它又可以控制其他的电子元件,就这么简单。那么接下来的问题是,程序是如何发展到今天这个样子的呢?
5 由二进制机器指令到汇编语言
1946年2月14日,世界上第一台电子计算ENIAC在美国宾夕法尼亚大学诞生。那时的程序员使用机器语言编写程序。38译码器的机器指令很简单,你可以很轻松的记住,但诸如101100000000000000000011 这样的机器指令恐怕就不那么好记忆了。我们可以想像,每天用机器指令写程序的人是多么的痛苦,多么的低效,多么的容易犯错误。于是聪明的灵长类动物想,可不可以使用一些简单的符号来代替那一长串的0、1组合呢。比如我们想让LED1点亮,我们就写 D1,想让LED6点亮就写D6。于是上面那个程序就变成了如下的形式:
D0 ;D0亮
D1 ;D1亮
D2 ;D2亮
D3 ;D3亮
D4 ;D4亮
D5 ;D5亮
D6 ;D6亮
D7 ;D7亮
就这样,世界上第一个汇编语言程序诞生了。我们使用 D0-D7 代替了 000-111,这样写程序就方便很多了。等整个程序都写完了,我们只要到指令表中找到对应的机器指令翻译过来就好了,比如 D4出现的地方我们就把它翻译成机器指令 100。由此也可以看出,汇编指令和机器指令是一一对应的,它其实就是机器指令的一个方便记忆的符号,因此被称为“助记符”。
虽然,汇编语言使软件的编写方便了许多,但是人工将汇编代码翻译成机器指令这一过程非常费时费力,容易出错的。于是聪明的灵长类动物编写了一个程序,这个程序能够自动查找汇编指令对应的机器码,就这样世界上第一个汇编语言编译器诞生了。
6 高级语言的产生
汇编语言是软件发展史上的一大进步,但它也同样存在了许多的不完美。其中一项就是通用性比较差。比如我们家的38译码器汇编指令是 D0-D7,而你们家的可能就是 A0-A7,同是38译码器,我写的程序就是不能用到你们家的译码器上。又比如同样是计算1+1,我们家的汇编代码是 ADD 1,1 ; 而你们家的汇编代码却是 AAA 1,1 ;
为了解决这个问题,聪明的灵长类动物又发明了高级语言,其中最著名的莫过于C语言了。人们只要按照C语言的语法书写自己的代码,然后把写好的代码交给一个专门的程序,这个程序会自动的,把你的C代码翻译成目标机器的汇编代码。从此程序员要计算1+1这个难题,只要在C语言中写 “a=1+1;” 这个简单的语句就可以了,人们再也不必去关心这条语句被翻译成汇编语言是个什么样子,因为这一切都被编译器代劳了。但一些灵长类动物也为此付出了一定代价,它们永远也无法理解,在C语言加减乘除运算过程中出现的那个所谓的“神秘的中间变量”到底是什么。
我们可以认为汇编是对机器语言的一次封装, C 语言是对汇编语言的一次封装,随后出现的C++语言是对汇编语言的又一次升级式的封装。但事情到此并没有结束,如今更高级的封装形式“控件”已经非常流行了,而且在不久的将来,还会有新的,更高级的封装形式出现。
遥远的海