《编码的奥秘》---学习编程一年半的体会

本人在校大学生,从大一下学期开始自学编程(JAVA)。到现在2018年7月2号也过了一年半的时间了。期间做过很多应用程序(PS:大多数都是做着玩的),比如做一个GUI聊天室(JAVA)、Android应用、Unity3D游戏(C#)、SSH整合开发一个WEB系统(完整版)等…虽然我这些都做过,但是…其中原理我却了解甚少,比如说JAVA的虚拟机的内存释放(垃圾回收器)、socket的连接过程(TCP三次握手以及四次挥手)、HTTP协议,这些东西我都不是很了解。

看过一篇文章,具体内容忘记了。说的是遇到一个解决数据库连接太慢的问题,有三种人去解决。我只记得2种人,因为太有比较意义了。第一种是通过网络抓包工具分析得到瓶颈,然后把问题解决了。另一种人是对这种数据库的经验已经很丰富,然后改了配置文件把问题解决的。当然在这个问题中,后者可以迅速的把问题解决,但是如果换了一个数据库,也许第二种人就不知道该怎么解决问题了。(PS:本人就属于第二种人,应用知道很多,理论懂得甚少。)这其实是非常不利于自己以后的发展的,IT新技术出来的太快了。自己也学过很多什么听上去吊吊的技术,也搭建起来了,手机上可以访问,一切正常。但是在这个过程中遇到的BUG基本上都是通过百度查找“得来”的答案。所以自己想了挺多之后,也是拿起来底层理论开始进行系统性的学习。最后这本书的博客只作为随笔,说给自己听,若有“有缘人”看到且看且珍惜吧。


编码的奥秘全书总结

这本书很通俗易懂,跟看故事书一样。从手电筒到ASCII编码,从十进制到二进制再十六进制,从组合电路到8080芯片,从开关到控制台汇编程序。这一个历经过程写的算是淋漓尽致了。


加法器

  • 加法器
    • 半加器(结果是xor,进位是and)
    • 全加器(考虑低位进位)

半加器逻辑图如下:
这里写图片描述
全加器逻辑图如下:
这里写图片描述

用加法器实现减法的方式是通过原码、反码、补码实现。

步骤是:

  1. 求减数的补码
  2. 被减数与第一步的结果相加
  3. 对第二步结果+1
  4. 减去最高位

(PS:以上步骤针对于被减数大于减数的情况下)


同步计数器

D型边沿触发器和时钟实现同步计数器(CP)

D型边沿触发器特性表(PS:上升沿有效,也就是上升沿的时候输出取反,现态为0,次态则为1)如下:
这里写图片描述
逻辑图如下:
这里写图片描述
波形图(PS:图片顺时针旋转90°就会得到0000->0001-…->1111的序列)如下:
这里写图片描述


RAM存储器

得到8位锁存器后。这样就得到拥有4根地址线的16x1的RAM存储器了。

D型触发器特性表:
这里写图片描述
D型触发器和写入信号实现8位锁存器:
这里写图片描述
通过3-8译码器选择写入数据,通过8-1选择器实现输出数据,得到8x1存储器:
这里写图片描述
再通过2-1译码器,得到16x1存储器
这里写图片描述

通过前面的实现我们可以得到一个方程:RAM阵列的存储容量=2的地址线的根数

通过这个我们就可以用16根地址线跟8个数据输入得到一个64Kx8的RAM
这里写图片描述

至于为什么是易失的,是因为继电器的电源来自于给这个RAM提供电源的设备(我们在这里称这个设备为总电源吧)。读到后面会知道,现在的计算机的RAM不用继电器,而是采用别的技术来实现,不过还是易失的就对了。


自动操作

接下来是自动操作。实现原理很简单,我们用一个振荡器来驱动一个16位计数器,计数器输入到64Kx8的RAM从而读取到RAM中的数据,最后再通过加法器跟锁存器实现读取RAM自动进行加法运算的操作。

不废话。上图:
这里写图片描述
发现灯泡亮的意义不大,改进这样就可以将锁存器的值通过在W=1时存入RAM中
这里写图片描述

到目前为止,我们一直“强调”着电路的实现。现在我们把这些实现当做细节忽略
这里写图片描述

这里,我们定义几个指令:

  1. Load 装载
  2. Add 相加
  3. Store 保存
  4. Halt 停止

通过这4个指令就可以这一项操作,并且停止

现在,我们将抽象的实现这个电路:
这里写图片描述
这个时候,我们只要把我们需要的操作存放到代码的RAM中即可实现自动操作

我们理解完高字节与低字节以及加法减法的设计后,我们又抽象出一个电路:
这里写图片描述
第一个锁存器保存指令代码,第二个锁存器保存地址的高字节,第三个锁存器保存地址的低字节。第二和第三个锁存器的输出组成了数据RAM 阵列的16位地址。

这个时候我们发现,用2个RAM太浪费了。可不可以只使用一个RAM呢?

由于我们已经知道每条指令都占3个字节,所以是可以的,只要在原来电路的基础上做一点改进:
这里写图片描述

这样,我们就可以通过控制面板向RAM写入程序。此时PC计数器开始从程序入口地址开始计数,通过代码和地址锁存器的共同作用执行所编写的程序

到此为止,我们已经做出一个通过 计数器(PC) 就可以让所编写的程序自动执行。不过我们发现:我们该如何规定程序入口呢?再是当我们计算机开机的时候PC是从什么位置开始呢?所以,我们引入一个 jump指令,而PC从什么位置开始我们先不做回答(因为与本课程无关,答案是从BIOS的ROM开始执行)。

因为我们增加了一个jump指令,所以需要改进的是PC计数器的一个取值。如下:
这里写图片描述
通过这种设计,我们就可以更改PC的值。让程序自动执行。(PC是一个振荡器,这与RAM的W输入不同)

到这里,我们的一个小型CPU已经被设计出来,而且这个CPU还与内存有着非常紧密的联系


从算盘到芯片

一个发展过程,不做阐述。


两种典型的微处理器

8080和6800PC机。位数不同,一个8位,一个16位。我们知道8位可以通过转换实现16位、32位、64位以及更高的的位数的处理。通过高低位字节实现。

8080是第三代微型处理器。8位。
6800是第三代微型处理器。16位。

由于每个不同的处理器都有对应不同的指令集,所以不做阐述。我们需要学习的是8086PC的指令集,一般汇编语言的教程都是用8086微型处理器,也是16位


ASCII码和字符映射

ASCII 码是 7位 编码。
Unicode 采用 16位 编码,每一个字符需要 2个 字节。

这里是有历史原因的。因为大多数国家用 7位 编码都不足以存储信息。所以每个国家都有自己的编码集

这样会导致一个问题:在一个txt文本中既写中文又写阿拉伯文,而txt的编码集设置为 GB2312 中国编码集。保存后,读取时会发现阿拉伯文变成乱码

于是Unicode出来了,将所有国家语言统一起来。此后又在Unicode的基础上为了提高效率而提出 UTF-8 的标准。


总线连接

总线是提供给计算机中每块电路板的数字信号的集合,这些信号可以分为 4类:

  • 地址信号。这些信号由微处理器提供,常用来寻址RAM单元,也可用来寻址连接到计算机上的其他部件。
  • 数据输出信号。也由微处理器提供,用来写入数据到RAM或其他设备。要仔细推敲输入(input)和输出(output)的含义。数据输出信号是从微处理器输出,变成RAM和其他设备的数据输入信号。
  • 数据输入信号。是由计算机的其余部分提供,由微处理器读入的信号。数据输入信号通常来自于RAM的输出,也即表示微处理器读入存储器内容。但是其他部件也提供数据输入信号给处理器。
  • 控制信号。由各种各样的信号组成,通常与计算机的特定处理器的控制信号一致。控制信号可来自于微处理器或从其他部件传送到微处理器。例如,微处理器可用一个控制信号来指示它要写一些数据到某一存储器地址。

这里的总线,并不是指地址总线、数据总线、控制总线,从数据输入输出的作用就可以看出。因为数据输入可以来自于其他设备(如键盘,而不是单一从的RAM获取输入),会响应中断信号


从操作系统开始到图形革命的内容自行理解吧~