您的位置:首页 > 理论基础

编码:隐匿在计算机软硬件背后的语言

2013-07-07 19:49 453 查看
最近读了本好书,特别推荐下《编码:隐匿在计算机软硬件背后的语言》。

作者Charles Ptezold很牛 世界上七位Mricosoft Pointeer之一。介绍了计算机编码的原理,结合生活中例子详尽描述了编码在日常生活中的应用(电报机、盲文凹凸字、胶片相机、UPC条形码)等,整体上用通俗易懂的语言描述了复杂的计算原理。同时该书也介绍了整个计算机发展的历史,一本很好的计算机历史书,知道了计算机发展的先驱人物。他们是:摩尔斯(电报机摩尔斯码)、布莱叶(盲文二元编码)、布尔、巴贝芝(差分机解析机,计算机雏形)、摩尔(定律)、香农(信息论)、迪摩根(定律
-A*-B=-(A+B) P94)、布莱尼茨、图灵、冯诺曼伊、赫兹(无线电波 周期)。

以下是部分摘录和总结:

结合布尔表达式 、电路原理介绍了继电器(线圈缠绕铁棒通电具有电磁感应,用来放大信号、自动控制开关)、逻辑门(继电器的组合、与门(用于加法器的进位)、与非门、或门、
或非门(只有两个输入都为0时,才输出1)
异或门(其输出1,其两个输入不能同时为1,用于加法器的相加)、反向器、缓冲器(什么都不做)、
半加器:求A、B的和 从而得到一个和输出 一个进位输出P99
全加器:在半加器的基础上处理进位

加法机需要144个继电器,这个数目如何得到呢?每个与门、或门、与非门都需要2个继电器,所以,一个异或门需要6个继电器。一个半加器由一个异或门和一个与门构成,所以它需要8个继电器。一个全加器需要两个半加器和一个或们,所以它要18个继电器。对于8位二进制加法机而言,共需要8个全加器,即18×8=144个继电器。

[align=left]当两个开关都断开时,电路有两个稳定状态,这样的一个电路称为触发器。[/align]

[align=left]触发器电路可以保持信息,换句话说,它有记忆性。它可以“记住”最近一次是哪个开[/align]
[align=left]关先闭合的。如果你遇到这样一个触发器,它的灯泡亮着时,你可以确定最近闭合的是上面[/align]
[align=left]的开关;而灯泡灭着时则是下面的开关。[/align]

[align=left]电平触发式[/align]
意思是说只有在时钟端输入从0变到1后(即高电平时),数据端
[align=left]输入的值才能保存在锁存器中。注意,在时钟端输入为1期间,数据端输入的任何改变都将反[/align]
[align=left]应在Q或-Q端的输出值上。[/align]

[align=left]这个电路就是所谓的电平触发的D型锁存器,它表示电路锁存住一位数据并保持至将来使[/align]
[align=left]用。它也可以称为1位存储器[/align]

[align=left]边沿触发:[/align]
[align=left]对于边沿触发器而言,只有当时钟从0变到1的瞬间,输出才会改变。在[/align]
[align=left]电平触发器中,当时钟输入为0时,数据端输入的任何改变都不会影响输出;而在边沿触发器[/align]
[align=left]中,当时钟输入为1时,数据端输入的改变也不会影响输出。只有在时钟输入从0变到1的瞬间,[/align]
[align=left]数据端的输入才会影响边沿触发器的输出。[/align]

[align=left]如何实现加法?[/align]
[align=left]如何实现减法?[/align]
[align=left]避免借位,采用加上一串1中在减去一串1(加1减100000000)的方法。[/align]
[align=left](减数从一串1中减去,差称为1的补数),组成求补器、8位加法器及一个异或门的组合。[/align]
[align=left]把减法转换为加法。P110[/align]

[align=left]你可以用某一位代替负号,当该位为1时就表示负数,为0时表示正数,这似乎也是可行[/align]
[align=left]的。但还有一种方法,它不仅能表示负数,而且还很适于把正数和负数相加到一起。这种方[/align]
[align=left]法的不足之处是你必须提前决定数字需要多少位.[/align]

[align=left]二进制数可以有两种不同的使用方法。二进制数可以是无符号的或有符号的,无[/align]
[align=left]符号的二进制8位数的表示范围从0~2 5 5,有符号的二进制8位数的表示范围从- 1 2 8~1 2 7。[/align]
[align=left]这些数本身不会告诉你它们是否带有符号。[/align]

[align=left]二进制中对应的系统称为2的补数。[/align]

[align=left]要计算2的补数得先求出1的补数再加上1,这等同于先求反再加1[/align]

[align=left]要计算2的补数得先求出1的补数再加上1,这等同于先求反再加1。例如,十进制数1 2 5是[/align]
[align=left]0 11111 0 1,要用2的补数来表示-1 2 5,可先取反得1 0 0 0 0 0 1 0,再加1就得到1 0 0 0 0 0 11。可用上[/align]
[align=left]表来验证这个结果。要回到原来的数只需同样的操作:取反后加1。[/align]
[align=left]这个系统使不用负号就能表示正、负数,它也使我们只用加法规则就可以随意进行正、[/align]
[align=left]负数运算。例如,计算- 1 2 7 + 1 2 4,利用上表即得[/align]
[align=left] 1 0 0 0 0 0 0 1[/align]
[align=left]+ 0 1 1 1 1 1 0 0[/align]
[align=left]= 1 1 1 1 1 1 0 1[/align]
[align=left]和是十进制的-3。注意上溢或下溢的情况 会忽略最高位而得到错误的结果。[/align]

[align=left]总结:在数字表示正负系统里,可以采用补数的处理方式把减法转换成加法。减法不过是负数的加法。[/align]
[align=left]减去某个数可以看作加上该负数的补数(要把3位负数转换成1 0的补数,需从9 9 9中减去它再加1,同理[/align]
[align=left]要计算2的补数得先求出1的补数再加上1,这等同于先求反再加1)。[/align]

[align=left]自动操作:[/align]
[align=left]jump 指令[/align]
[align=left]在一开始进行加法运算时,我们把数据和指令码分别存储到两个不同的RAM上,为了使两者在同一个RAM并存[/align]
[align=left]需要使用jump指令[/align]
[align=left]条件指令[/align]
[align=left]在进行乘法运算(即理解为多个加法运算 几个几加几遍)时,但我们不要重复指令及浪费空间。[/align]
[align=left]在用jump指令循环求和时需要在一定条件下停止运算,需采用条件指令 指定停止条件。[/align]
[align=left]需要添加零锁存器及控制信号来模拟条件控制。[/align]

[align=left]以下是对一个问题的思考及解答:[/align]
[align=left]++++++++++++++++++++++摘自P168++++++++++++++++++++++++++++++++++++++++++++[/align]

[align=left]我们想让转移指令做的是使循环过程只重复所需的次数,这就是条件转移,它实施起来[/align]
[align=left]并不困难。我们要做的第一件事情就是增加一个与进位锁存器类似的1位锁存器。因为只有8[/align]
[align=left]位加法器的输出全为0时它才锁存1,所以叫它零锁存器:[/align]



[align=left]只有当或非门的8个输入全为0时,其输出才为1。同进位锁存器的时钟输入一样,只有当[/align]
[align=left]加法、减法、进位加法或借位减法指令运行时,零锁存器的时钟输入才锁存一个数,这个被[/align]
[align=left]锁存的数值叫作零标志位。注意它,是因为它似乎行为相反:如果加法器输出全为0,则零标[/align]
[align=left]志位为1;若加法器输出不全为0,则零标志位为0。[/align]
[align=left]利用进位锁存器和零锁存器,可以在指令表中再添加四条指令:[/align]
[align=left]操作码 代码[/align]
[align=left]L o a d 1 0 h[/align]
[align=left]S t o r e 11 h[/align]
[align=left]A d d 2 0 h[/align]
[align=left]S u b t r a c t 2 1 h[/align]
[align=left]Add with Carry(进加位,使用进位锁存器保存低位相加的进位值) 2 2 h[/align]
[align=left]Subtract with Borrow(借减位) 2 3 h[/align]
[align=left]J u m p 3 0 h[/align]
[align=left]Jump If Zero (零转移) 3 1 h[/align]
[align=left]Jump If Carry (进位转移) 3 2 h[/align]
[align=left]Jump If Not Zero (非零转移) 3 3 h[/align]
[align=left]Jump If Not Carry (无进位转移) 3 4 h[/align]
[align=left]H a l t F F h[/align]

[align=left]每个操作码在存储器中占1个字节。[/align]

[align=left]例如,只有当零锁存器输出为0时,非零转移指令才转移到指定地址。换句话说,如果上[/align]
[align=left]一次加法、减法、进位加法和进位减法指令计算结果为0,则没有转移发生。实现这个设计只[/align]
[align=left]需在实现常规转移命令的控制信号上再加上一个控制信号:如果为非零转移指令,则只有当[/align]
[align=left]零标志位为0时,1 6位计数器的置位信号才被触发。[/align]
[align=left]利用上述代码实现两个数的乘法所需的操作可由如下开始于地址0 0 1 2 h处的指令完成:[/align]



[align=left]正如我们所设计的,循环一次后,位于1 0 0 4 h和1 0 0 5 h处的1 6位数等于A 7 h乘以1。上图中[/align]
[align=left]的这些指令把字节从1 0 0 3 h处装载到加法器中,此字节为1 C h。再把这个字节与0 0 1 E h处的数[/align]
[align=left]据相加,此处数据正好是停止指令,但当然也是有效数字。把F F h同1 C h相加与从1 C h减去1的[/align]
[align=left]结果相同,都等于1 B h。这个值不为0,所以零标志位为0,字节1 B h存回到地址1 0 0 3 h处。接[/align]
[align=left]下来是一条非零转移指令,零标志位没有置为1,所以转移发生。下一条指令位于地址0 0 0 0 h[/align]
[align=left]处。[/align]
[align=left]记住,存储指令不会影响零标志位。零标志位只能被加法、减法、进位加法、借位减法[/align]
[align=left]指令所影响,因此它同这些指令中最近一个执行时所设置的值相同。[/align]
[align=left]循环两次后,位于1 0 0 4 h和1 0 0 5 h处的1 6位数将等于A 7 h乘以2。而1 B h加上F F h等于1 A h,[/align]
[align=left]不是0,因此又返回到存储器顶部。[/align]
[align=left]循环到第2 8次时,位于1004h 和1 0 0 5 h处的1 6位数等于A 7 h乘以1 C h。位于1 0 0 3 h处的值等[/align]
[align=left]于1,它将加上F F h结果等于0,因此零标志位被置位。非零转移指令不再转移到存储器地址[/align]
[align=left]0 0 0 0 h处,相反,下一条指令为停止指令。至此,我们完成了全部工作。[/align]

============================摘抄结束===============================
解释:第一遍读并没有理解该机制,多读几遍后貌似理解了。最大的疑问就是标红的部分,为什么此时1003h处为1呢?可以多读几遍蓝色字体。在第一次加载1003h时值为乘数,以后在地址存的是1003h与停止符(FFh)的和 相当于乘数1Ch减1,直到进行第1Ch(即十进制28)次循环, 相当于减1进行了27次 故此时值为1了,之后就明了了,零标志位被置位,进行停止指令,而不再跳转到0000h处了。
=================================================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: