对于学习计算机程序设计的人来说,应该尽早了解“错误”(bug)这个术语。当你编写代码时—特别是采用机器语言—是非常容易出错的。输入一个错误的操作数已经很不妙了,如果输错的是一个指令代码的话,情况会怎样呢?当你准备输入10h(Load指令)的时候,却输入了11h(Store指令),造成的后果是:期望的数据不会被机器加载,而该地址的数据还会被累加器中的内容替换掉。
一些错误可能导致意想不到的结果。假设你使用Jump指令跳转到一个地址,而该地址没有存放任何合法的指令,或者你偶然误用Store指令覆盖了其他指令,类似的情况都有可能发生(而且会经常发生)。
甚至上述乘法程序中就存在着一个错误。如果你把程序执行两次,第二次得到的将会是A7h与256相乘的结果,并且程序会把这个结果与第一次运算的结果相加。这是因为程序执行一次之后,1003h地址保存的数值是0。当第二次执行时,FFh与这个0相加的结果不是0,因此程序会继续执行直到它变为0。
我们已经利用该机器完成了乘法运算,用类似的方法也可以进行除法运算。同时,前面也讲过,利用这些基本功能还可以进行平方根、对数、三角函数等运算。机器所需要的仅仅是能够做加、减法的硬件以及利用条件跳转指令执行代码的方法。正如程序员经常挂在嘴边的一句话:“我可以用软件完成其他工作”,这些工作我们都可以编程实现。
当然,软件可能是很复杂的。有很多专门讲授程序员如何用算法(algorithm)解决特殊问题的书,本书不打算讲这些内容。目前我们一直讨论的都是自然数,并没有考虑如何在计算机中表示十进制小数,本书将在第23章讨论这个问题。
前面不止一次强调过,这些硬件部件早在100年前就发明出来了。但是,本章所设计的计算机在当时却并没有被创造出来。当继电器计算机在20世纪30年代中期被设计出来的时候,很多包含在其中的概念还并不为人所知,直到1945年左右世人才开始慢慢了解它们。例如,在当时,人们仍然尝试在计算机中使用十进制数而不是二进制数;而且计算机程序也不是完全存储在存储器中的,有时候它们会被保存在纸带上。特别是在早期的计算机中,存储器非常昂贵并且体积庞大,不论在100年前还是在今天,用500万个电报继电器构建一个64KB的RAM阵列都是令人感到荒唐的事。
编码——隐匿在计算机软硬件背后的语言
250