编程的理想

2005年5月20日

编程的理想

范德成

我学编程是从 BASIC 开始的。当时还在初中时候。老师第一次教 BASIC 的时候,教的还是像计算器一样的功能。之后,当我第一次翻开我爸爸当年的 BASIC 教程的时候,映入我眼帘的已不仅仅是计算器了,而是一台可编程的计算机。

BASIC 还只是过程型语言,连结构化语言都算不上,但是正是过程型语言体现了冯·诺伊曼的设计:把程序存储在计算机上,然后计算机一边读程序,一边执行。当时我还不懂汇编程序。当我懂得汇编程序之后,我明白了 BASIC 是一种类似汇编的解释执行的语言。

BASIC 语言的确是一种特别的语言。在它里面可以调用机器代码,可以修改任意内存地址中的内容,还有一些语言内置的中断功能。

到高中时,我学了 FOXBASE 和 QBASIC。QBASIC 已经是结构化的语言了。它已经让 BASIC 那令人感到麻烦的 GOSUB 变为可爱的 CALL 了。栈是解释器自己管理的。同时,QBASIC 那种蓝蓝的界面,让我觉得很可爱。

进大学以后,学了 C 语言。当然 C 语言不是一种产品,于是就要找 C 语言的编译器。老师一般都会让我们用 Turbo C 2.01。当然,这是一款不错的产品。但是我自己却另外找了一个 QuickC 2.5。现在想想,Turbo C 2.01 当时已经开放免费使用了,但 QuickC 2.5 还不是免费的。我用的就必然是盗版了。不过 QuickC 2.5 本身还是挺吸引人的。虽然它编译出来的 exe 没有 Turbo C 编译出来的小,速度也慢一点,但是它默认编译的程序就有栈溢出检查,这对于我来说是一个不小的惊喜。而且 QuickC 那蓝蓝的界面与黑黑的帮助窗口,给人的感觉是一个计算机专家……

但是我是先学 BASIC 语言,然后再学 C 语言的。虽然由于我先学了微软的 QuickC 2.5 程序员手册,让我对 C 语言中的概念的理解超过了好多同学,但是 C 语言本身还是不带完整的缓冲区溢出检测的。而以前写 BASIC 则从来没有这样的担心。所以写 C 代码必然要投入更多的心思。然后我就在想,编译器的目的就是要产生高速的代码。如果它都要让编译出来的程序做缓冲区溢出检查,如现今的 C#,那效率必然受影响。而解释器的目标则是易用,它在运行程序的时候做缓冲区溢出检查是当仁不让的事情。

这样想着,我就有一个设想,是不是我能自己做一个 Turbo C 程序的解释器呢?这样能在解释执行的时候发现缓冲区溢出的错误,那么可以更正这样的错误,然后在 Turbo C 中编译之后,就可以安全地运行了。

因为以前用 BASIC 的时候用过微软的 BASICA,所以我打算把这个项目命名为 Mosaica。不过由于大学时候能力也不是很强,虽然写过一个科学算式解释器,但能力还是有限,再加上自己也不努力,所以最终还是没有写这样的一个解释器。

然后我又想了,当时操作系统用 Windows 的时候,多任务是很方便的。但是操作系统用 DOS 的时候,多任务如何实现?当然可以模仿 Windows 的做法,用时钟中断,但是如此高级的东西还需要硬件支持。如果没有硬件支持,我想最简单的办法莫过于是写一个支持多任务的解释器。而且,使用解释器有一个很大的优点:管程(monitor,即执行过程中不会被切换的函数)是非常容易实现的。当然,缺点就是所有的程序执行起来都会比较慢,毕竟是解释执行的嘛。

多任务的话题先讲到这里。

在大学里,我第一次用 java 的时候,心想这下好了,可以有一个既面向对象又有缓冲区溢出保护的执行系统了。C++ 里面缓冲区溢出保护要程序员自己完成,因此很可能出错。缓冲区溢出保护不仅仅在程序的功能方面有作用,而且在安全方面有作用,比如微软的好多补丁都是做缓冲区溢出保护的。另外,在同一个系统中运行的多个程序,如果互相之间可以访问对方的内存,那么缓冲区溢出就更有可能是一个全局性问题了。这个问题在 Windows NT 上是没有的,因为每个应用程序都有自己的虚拟内存地址。而在 Windows 98 上,虽然应用程序相互之间也是分别有各自的虚拟内存地址,但是系统的一部分虚拟内存地址却是可以被程序看见的,于是出错的程序对这块地址的修改往往导致系统崩溃。

但是自打到了单位,开始做数据库相关的应用程序的时候,发现自己以前没有多少写数据库程序的经验。于是这方面又得有新点子来提高工作效率了。但编程并没有对过去说拜拜,而应该融合过去与现代,现代与未来,把计算机还没有诞生的年代与计算机消失的年代一起都放在一块儿,变成一个大融炉了,这样才能理解一切编程的现象。

留下您的评论