02 January 2008

CS truth and illussion

From CSDN :

幻象与真实--计算机的本质 

一、计算机的本质
计算机的本质是一个复杂的数字电路,数字电路只能处理和输出高低两种电位组成的信号,所以计算机只认识高低两种电位状态!
任 何人类的观念(比如数字,字符,图像等),在计算机里都被转换成这两种状态,再通过硬件电路或者程序的方式,使对这些状态的输出,符合这些观念本身应有的 规律和形式,因为人看不到内部的转换和处理,只看到外部输出的样子,于是,在人看来,计算机可以完成多种多样的任务,相当神奇!
计算机能够完成多种任务的两大基石:
1.编码:用计算机的高低电位对应外部事物的各种状态。
2.输出:以外部事物的样子把编码处理后的结果展示出来。(可以通过硬件电路也可以通过软件程序)
编码的概念:
用少量简单基本的符号,选用一定的组合规则,以表示出大量复杂多样的信号。基本符号的种类和这些符号的组合则是一切信息编码的两大要素,例如用10个阿拉伯数码表示数字,用26个英文字母表示英文词汇等,这就是编码的典型案例。计算机中,广泛采用01两个基本符号组成的基2,或称二进制码。(一般用高低两个电位表示10
--《计算机组成与结构》
二、具体事例
1.字符
编码:以ASCII字符集编码为例,将数字、大小写字母、标点符号、控制字符等128个符号,对应到 0x0 0x7e 上。也就是说用 0x0 - 0x7e 128个状态编码了128个符号。
输出:早期的计算机通过符号显示器这一硬件来将字符显示出来。比如当接收到计算机发过来的一个字节 0x58 时,crt将根据0x58指向的字符rom中的高低电位控制电子束的开关,在屏幕上组成图形“X”。
2.数值
编码:数值是表示数量多少的数据。对数值数据的编码,计算机中有:原码,补码,反码。
处理,计算机的运算电路,根据数值编码方案设计,使输入状态经过电路处理后得到的输出状态符合加减乘除等运算规则。比如,输入 ▂ 和 ▂ 输出 █ █ ,符合 10 + 01 = 11
输出:将结果数字转换成ascii编码,送字符显示设备。比如将 5 )转换成ascii字符 5 ▂ ▂ █ █ ▂ █ ▂ █),然后送显卡画图。
3.图像
编码:将点的位置和颜色等信息,对应到一定的高低电位序列,实现编码。
输出:显示设备根据点的信息,在显示器上输出一个点,大量的点按一定规则排列,形成人们观念中的图像。
三、一个重要理念:计算机是一部状态机,不是数字机。
计算机不认识数字,只认识高低两个状态。
数字只表示高低电位的排列状态。比如,0xb8 ,它并不代表数量,只代表电位排列状态,化成二进制为:10111000 ,就是代表: █ █ █ ▂ 这一状态。
自然界中数字的概念:
表示事物个数的符号。
进制的概念:
数学上的进位制本来是人们为了计数和运算的方便而约定的,约定逢二进一,就是二进制,约定逢三进一,就是三进制,依次类推。不同的进位制,除了繁简的差异外,没有任何本质上的区别。也就是说,不同的进制,只是自身的形式不同,其表示数目的本质是一样的,比如二进制100与十六进制4 都表示一样的数目,他们本质是一样的,仅仅形式不同。以计算机举例,内存中有 █ █ ,你可以用二进制的概念叫他为 1011 ,亦可以以十六进制叫他为 b ,也可以以十进制叫他为 11 。无论怎么叫,他内存中的状态始终不变。
因为计算机里只有高低两种状态,所以数字无论是二进制还是十六进制,只是这种状态排列的一种表示方式。在这里数字已经失去了它本来的表示数量功能的意义了,取而代之,这里表示电位排列状态。
我比较习惯把高低电位用符号表示,而不用01.因为用数字0 1 来表示高低电位,潜在的意思是:这个东西是数字,而数字是符合运算规则的。其实,计算机内部很多东西都不是数字,比如mov指令: █ █ █ ▂ ,它并不代表一个数值,只是一个cpu能识别的电位序列信号。如果用0 1 来表示就是,10111000 ,看上去就是一个数字。还有,是否符合运算规则是内部电路来决定的,如果电路设计成 输入 ▂ 和 ▂ 输出 █ █ ,那么就符合加法运算,但如果设计成输出 ▂ ▂ 呢,再表示成输入:10 01 ,输出:00 就比较别扭了。
如果克服这些障碍,把 0 1 仅仅看成是计算机的两种状态,那么表示起来还是很方便的,因为这时不仅可以用 0 1 ,还可以转化成更方便的十六进制,象上面那条 mov 指令就可以表示成 10111000 或者 十六进制 b8 。但要记住,10111000 也好 b8 也好,只是内存中高低电位状态分布的一种表示,并不表示数量。
知道这些,就容易理解:汇编程序在汇编过程中,直接查表把ASCII 码组成的 mov 汇编成 0xb8,这里如果把 0xb8 看成一个数字,就容易迷惑,把它想象成一个高低电位分布的状态,就容易理解了。
四、ASCII 里的数字字符,与真正的数字,有时让人迷惑。
以无符号整数5为例,在计算机屏幕上看到的5,与计算机内部以原码表示的数值5是不同的。在计算机屏幕上显示的5是一个字符,它以ASCII编码,在计算机内部的电位序列为: ▂ ▂ █ █ (二进制 0011 0101 十六进制0x 35)。
而计算机内部原码表示的数字 5 电位序列为:▂ ▂ ▂ ▂ ▂ (二进制 0000 0101 十六进制0x 5)。
就通常的输入手段来说,通过键盘,在编辑器里输入,不能手工输入机器数 5 ,因为编辑器程序把键盘输入的扫描码转换成了ascii编码,但老式计算机可以通过开关,打孔等输入方式输入机器数。
要想得到机器数5 ,必须借助编译器等第三方程序。比如汇编语句“ db 5 ,这里的 5 仍然是一个ASCII 码,通过汇编程序处理后,才在内存中得到真正的机器数 5
c语句“int x=5这里的5也是ASCII ,编译后才是真正的5
计算机语言的源程序,都是ASCII码组成的,尽管如此,他们还是会提供一些语法,以便确定编译后,你到底需要ASCII还是真实的数字,比如c char x = 5;与 char x = 5’;
总之,人眼可以看到的数字,就是以ASCII形式编码的字符,而真正数字的机器码,人眼是看不到的。一般计算机语言都会提供一种语法,来确定最后编译得到的是哪种形式的编码。
五、汇编与反汇编
汇编过程:
语句“ mov ax 5 ”在机器内部的表示为一堆ASCII编码:
符号形式 二进制 十六进制
m▂ █ █ ▂ █ █ ▂ █ 01101101 6d
o▂ █ █ ▂ █ █ █ █ 01101111 6f
v▂ █ █ █ ▂ █ █ ▂ 01110110 76
空格( ▂ ▂ █ ▂ ▂ ▂ ▂ ▂ 00100000 20
a▂ █ █ ▂ ▂ ▂ ▂ █ 01100001 61
x▂ █ █ █ █ ▂ ▂ ▂ 01111000 78
,( ▂ ▂ █ ▂ █ █ ▂ ▂ 00101100 2c
5▂ ▂ █ █ ▂ █ ▂ █ 00110101 35
经过汇编程序得到cpu可以运行的真实的指令:
符号形式: █ █ █
二进制形式:101110000000010100000000
十六进制形式:0x b80500
反汇编过程,这里只反汇编为16进制数表示的结果:
还是这个语句:
█ █ █
以半字节为单位,转换为16进制数的ASCII
█ █ 0x b 转换为ASCII 编码的 “b0x62 为:█ █
0x 8 转换为ASCII 编码的 “8 0x38为: █ █ █ ▂ ▂
0x 0 转换为ASCII 编码的 “00x30为:▂ ▂ █ █
█ 0x 5 转换为ASCII 编码的 “50x35为:▂ ▂ █ █
0x 0 转换为ASCII 编码的 “00x30为:▂ ▂ █ █
0x 0 转换为ASCII 编码的 “00x30为:▂ ▂ █ █
把这些反汇编后的数据送到显存,屏幕上就显示出ASCII b80500 了。

No comments: