《编码》读书笔记

前言

书名:《编码:隐匿在计算机软硬件背后的语言》
英文名:Code: The Hidden Language of Computer Hardware and Software
作者:美国人Charles Petzold
去年买的书,读了一遍总感觉没读透,也可能是读了内容忘了,所以又读了一遍。

简单内容(1-12章节)

前面的内容有上过大学的电气、电子、计算机的学生看起来都不会很吃力,我把它分为几个部分:

1.阐述信息的组成,信息的主成有现象(光、电、声音、文字、图像),并且包含现象的获取顺序,比如你把一句话的顺序、主谓宾搞混了就和原来不是一回事了,还有我们阅读的文字如果约定的顺序不一样获得的信息也会不同(典型的就是古人的书写习惯是先右后左),这种顺序包含空间顺序也包含时间顺序。
2.从电报机聊到编码,这个就比较直观了比如摩斯电码SOS是:··· --- ···三短三长三短一般比较好辨认用于国际通用求助,在markdown里面 ```代表代码块。不管是否加密,总是接收方和发送方要达成一定的协议,否则通讯就无法进行。
3.根据继电器的特点不是0就是1的两种状态,我们选择使用二进制作为计算机的内部语言。之后就继电器的基础模型详细描述了《数字电路》里面讲的逻辑门,最基础的就是缓冲器、反相器、非、与、或、异或门四种逻辑门电路,还有他们的衍生组合:与非门、或非门、与或非门,基于这个概念我们就可以用继电器或者三极管自己造出这些门。

数字计算器的组成(13-17章)

使用数字电路逻辑门我们可以制作出译码器、振荡器(蜂鸣器、晶振时钟)、R-S触发器、D型锁存器、选择器、边沿触发器、分频器、计数器等。

而加法器也没有什么特殊的同样是用逻辑门造出来的,首先我们考虑两个一位二进制数相加。画出输入输出表格我们知道需要一个异或门。

(A || B) && !(A && B)=A XOR B  //异或门

加和输出:A XOR B
进位输出位为:A && B
这种叫做半加器,两个半加器和一个或门可以得到一个带进位输入的全加器。
8个全加器(7个全加器和1个半加器也行)就可以组成一个8位+8位的8位加法器。
可以多重套娃用加法器叠加起来做16位、32位的加法器都没问题。但是这种方法太浪费了,如果让你计算一个很大的数可能要造N多个加法器。
所以就需要用锁存器(用触发器组合)了,顾名思义就是用来存上一次的结果以便于用来进行下次运算,中间加一个选择器用来控制B端输入是锁存器还是外界输入。这样就得到一个加法器了。

自动操作的数字计算器

为了一次性输完一组数让他们自己去求和就需要两个东西一个就是存数的RAM(随机访问存储器)、另一个是时钟信号(拓展一下:51单片机晶振频率12Mhz,一次机器周期等于12个时钟周期就是1微妙)。
在一个8位锁存器的W写操作端添加一个3-8译码器进行W端有且仅有一个为1,在锁存器输出端添加一个8-1选择器进行输出选择,如此定向输出定向输入,三位用来控制地址、一位数据输入、一位写操作端就可以管理8X1的RAM一共1byte字节的数据。
把这套输入和一个输入位再加到另一个8X1的RAM上就可以组成一个8X2RAM一次可以得到两个RAM的输出。这样纵向拓展下去可以无限套娃得到8XN的RAM,但是未免太傻了。一般情况是把N取8再进行横向扩展,增加地址位得到一个65536(2的16次方)位锁存器,此时地址位为16,输入输出8位,可以储存65536个8比特位(1字节)的数据,共64KB(千字节)。
这大概需要由500万个继电器进行组装,所以RAM是需要带电工作的,一旦掉电数据就丢失了。
有了这两个东西就可以开始尝试组装一台自动操作的计算器了,稍加改进就是一台可以称之为计算机computer的东西了。

自动加法器

利用16位计数器我们可以顺序对RAM进行寻址,那么我们就可以在RAM上面顺序进行读写操作,把需要相加的数据逐条输入。之后装上振荡器并清零16位计数器,机器就像上了发条一样,自动在时钟信号的指挥下,逐条读取数值与锁存器数值进行加法操作,并把结果保存进锁存器,然后如此循环。当计算结束后你必须马上记录结果,不然一旦进入下一个寻址周期,那么结果就不准确了。

概念机

如何让机器听话呢?再加上一片RAM用来存储代码就可以,这些代码会影响机器的运行状态,比如说控制加法器读另一片RAM的数、向锁存器RAM写数、比如说让机器停下来不再受晶振影响,这些需要把8位代码的输出用逻辑门和需要控制的器件连接,达到控制他们的目的,进而控制机器运行。而每一个代码就对应一个英文操作码方便人们阅读,之后精简扩充后就是汇编语言。
通过对这个模型的优化改进增加操作代码集和控制元件的添加后,还是发现这个机器比较笨重,因为它不能对之前保存的数进行访问,原因在于数据块RAM地址位的控制权不在代码RAM手上,因此把一个代码扩充到3字节,分别保存1字节操作码2字节地址。
经过整合可以把两块RAM缩减到一块,代码RAM不但可以被读也可以被写。但是也造成一个指令周期变长为4个时钟周期,缩小了机器性能。之后就是指令集和机器控制元件的一些小调整。
机器的硬件和软件组成都完成了,就此创造了非凡机器的开端,万恶之源,由处理器、储存器、输入输出设备共同构造的数字计算机的时代。
其中处理器CPU包括:累加器和算术逻辑单元ALU,以及寻址用的程序计数器。
现在我们可以讨论一下加法之外的算术了:
1.整数减法:改变数据结构,用补码代替原码表示数字,这样做出来的加法不受变化,但是可能有人会觉得A=5,B=3这时候A-B是需要对B取反再加1的会不会增加操作的周期?其实不用担心取反只要加反相器,而加1的操作直接在加法器的进位置位1就行啦。所以不会增加操作时间。
2.整数乘法:依然使用补码表示数字,使用跳转语句和零标志位判断结合的新的四个操作码(JZ,JC,JNZ,JNC)进行加法的多次操作从而模拟乘法。
3.其他算术,依然可以使用加法器进行模拟,形成固定算法。

计算机历史(18-19章)

详细介绍了人类文明从无到有逐渐发明了计算机以及工艺改进的历史,其中出现了一系列杰出人才,他们不一定是计算机科学家,很多都是基础领域如数学、物理、化学领域的科学家。
主要介绍了两种典型的微处理器。因特尔Intel 4004和摩托莫拉Motorola6800。
微处理器性能衡量标准:
1.数据通路宽度,也就是我们常说的4位、8位、16位处理器。
2.最大时钟频率(主频),常用单位HZ,KHZ,MHZ,决定了计算速度。
3.可寻址空间,并不代表RAM的容量,只是它的寻址能力决定可以装上多大的RAM。

现代计算机的主要构成(20-25章)

随着集成电路IC技术的使用,英特尔在1971年制造了第一个微处理器CPU:
1974年Intel8080主频2MHZ,一条指令位4-18个时钟周期,所以需要2-9微妙。
新增6个寄存器,BCDEHL,A代表累加器,MOV指令就是对他们的值做操作。
同时还增加了逻辑运算的功能。
引入了栈的概念:其实栈也是一段普通的RAM存储空间,但是它是被独立划分出来的,配合一个特殊的寄存器作为栈指针(SP)使用。而且栈在物理层表现的也是从下到上堆放,所以栈是会向上溢出覆盖程序代码的。向下SP也会溢出。
同时为了和外界打交道,8080还引入了中断的概念,启动EI中断后,INTE端输入置1后芯片响应中断。键盘中断指令RST 4,跳转到0020h处开始处理键盘读取代码。
现代处理器一般都会自带一个RAM用作Cache高速缓冲存储区。
摩尔定律:微处理器中的晶体管数量每18个月翻一倍。

为了让计算机更好地组装我们引入总线的概念,总线是数字信号的集合包括:
1.地址信号
2.数据输出信号
3.数据输入信号
4.控制信号
总线还可以为计算机上的不同电路板供电。

操作系统:
随着计算机的使用我们需要解决一下计算机系统的交互性和便捷性的问题了。
为了使得程序储存和数据储存持久化,磁盘技术就被引入到计算机系统内,磁盘不能直接被微机访问,而是需要先跑一段程序控制内存调用磁盘数据,然后CPU再来访问内存读取代码进行数据计算。
接下来解决输入和显示的问题,输入使用键盘,输入使用显示器。
键盘是也是一个电子设备,按下一个按键就会发出中断信号引导CPU处理读取按键的键值。而显示器就稍微复杂一点,为了使得输出可读性高显示器被设计成点阵的形式,一个大点阵又分为整齐的行列从而划分出若干单元。通过显示适配器(我们常说的显卡,里面有一块ROM只读存储器可以把字符信息转换成显示点阵信息)CPU就可以把需要回显的信息“打到公屏上”了666。按键回显这个过程需要程序支撑。
磁盘就像一个文件柜,管理他是十分麻烦的事情,这时候我们也是需要一个自动化的方法来管理。
和底层的硬件打交道始终是一件麻烦事情,你需要阅读特定型号的电子手册才能知道相应的输入输出及使用方法,所以这也是我们想要解决的。
操作系统就是用来解决人们这些懒惰想法的,CP/M操作系统包括:
1.基本磁盘操作系统BDOS
2.控制台命令处理程序CCP
3.应用程序API接口BIOS
在开机通电的时候ROM内存储了一小段引导程序会自举并引导磁盘加载到内存中,从而实现操作系统的加载这个过程叫做引导。

到此我们终于实现一台还可以的计算机了,当然和现代计算机比他并不够好,但是现代计算机还是遵循他的原理制造。

以前在学习51单片机时,我们常常喜欢用定时器中断来进行延迟操作,但是如果在互联网上查询x86汇编的延迟程序一般都是使用循环空语句来增加执行时间的。一开始我以为PC的CPU是没有片内定时器这个东西的。然而其实不是,CPU片内定时器和单片机比只会多不会少学习完操作系统我们知道如果要找底层硬件中断的话需要去查阅BIOS的中断语句得到:

MOV AH,86H
MOV CX,0x001E
MOV DX,0x8480
INT 15H
//以上代码执行一个2秒的延迟

事实上现代操作系统更为复杂主要包括以下五大功能:
1.进程管理
2.存储管理
3.设备管理
4.作业管理
5.文件管理
现在的Bios系统一般都集成在主板的ROM上,所以当装好机以后没有安装操作系统的电脑也能像古人们一样进行操作,而安装好更高级的操作系统后,你的电脑就成为一台现代意义上的个人计算机了。
因此如果现在我们要组装一台计算机,首先要买一块电源、一块主板(主板集成了总线和主板操作系统)、一块CPU处理器(有些型号集成了显示适配器,Intel或AMD生产)、一块显示适配器(显卡GPU,英伟达或者AMD生产),一块或多块内存条(RAM),一个硬盘(磁盘),以及显示器和鼠标键盘等外设。最后还需要安装Windows或者Linux等操作系统。现在你就可以开始正常使用一台个人电脑了。

打开你的电脑查看配置,一般显示适配器有两张,一张是集成显卡,一个是独立显卡GPU,这就对啦。所以有时候不要太纠结于那种传统架构下的专有名词,因为他们很多都是交叉的。

GPU是为了图像处理而生的,它在结构上并没有专门为图像服务的部件,只是对CPU的结构进行了优化与调整,所以现在GPU不仅可以在图像处理领域大显身手,它还被用来科学计算、密码破解、数值分析,海量数据处理(排序,Map-Reduce等),金融分析等需要大规模并行计算的领域。

读后感

人类呕心沥血发明了计算机,为了做人口普查,为了数学研究,为了在物理上计算原子弹的数据,计算航天轨道。而这一切都发生在我们出生前了,我们站在了巨人的肩膀上,构建出了现在的生活,你用它来点外卖、看电影或者是做科学研究。计算机的应用不分贵贱,技术的可获得性造成了算力的浪费,可是哪怕我在这里敲下这些文字(毫无营养毫无乐趣),但他确实帮到了我。
有一个疑惑,在先贤面前我们都是蝼蚁吗?其实有时候很悲观地说就是这样的,我们应用计算机技术的能力可以说炉火纯青,但是即使掌握了如此熟练的理论基础的前提下让一个伟大的国家从零开始设计计算机也是相当困难的。计算机和其他现代工业品一样,离开了完整的供应体系和市场全球化都是行不通的,并非我们过于渺小,而全在于术业有专攻而已。
弗洛伊德认为随着人类文明的进步反而会增加人类的痛苦,哪怕他存在的时代还没有计算机。事实上,科技发达文明进步的今天,我们也依旧没有逃出弗洛伊德的预言。不过要使自己快乐很简单,不要被生活束缚了,计算机始终是服务于人的,你爱让他干嘛就干嘛只要你有驱使他的本事。
永远记住技术是服务于你的,而不是说到处寻求一种技术只是为了有朝一日变现,但是现在的市场形势就是这样,经常能看到有人力在抱怨研究生不适应工作,也经常看到他们赞赏部分大专生干活很伶俐。虽然我的学历不高,科研水平和工作水准可能都不高,但是我还是希望我的读者包括未来的我,要认识到技术是会迭代的,任何没有准入规则的行业只会一直内卷下去。
我本人也很反感那些动不动就拿技术栈谈话的人,因为任何技术都是在变革的,企业主们永远只是把你们用做赚钱的机器而已,招一批当前成熟技术栈的人,过几年技术革新了就换掉。企业不但没有培养人的意识而且也不给学习的机会,就老拿研究生不适合市场需求开炮,要是按照他们的逻辑高等数学学了也是白学,小学一年级就该去培训班学Spring框架。
写到这里如果可以,我想我自然是不愿意打工的,因为人做什么都可以活着,但是如果可以从事自己喜欢的事业那也就勉强再做几年资本家的奴才吧,可是要需明白这始终不是什么长远的头路。

关于MCU

MCU,单片微型计算机,单片机。
个人电脑CPU基本被Intel垄断了,同样的因特尔也有涉及单片机市场,比如80C51和89C51就是他们家设计的,并且十分便宜一般在两块钱到五块钱不等。
STM32单片机则是ST(意法半导体)公司使用arm公司的cortex-M3为核心生产的32bit系列的单片机,他的内部资源(寄存器和外设功能)较8051、AVR和PIC都要多的多,基本上接近于计算机的CPU了,适用于手机、路由器等等。一块差不多十块钱左右。

MCU和CPU的主要组成部分其实都差不多,无非是运算器、控制器、存储寄存器、高速缓冲区等基础部件组合而成的。不同之处在于它们的硬件电路实现不同,个数不同,功耗不同,计算能力不同,但都提供相同的基本功能。俗话说麻雀虽小五脏俱全,MCU可能就是这样的存在吧,因为他自己就是一台电脑,不像CPU还要依赖别人才能组成一台电脑。可是这两个电脑也不是一个维度的,他们的应用场景和使用方法还是有很大区别的。

思考1:关于JVM虚拟机

JAVA程序运行在JVM虚拟机内部,JVM跑在操作系统上。那么虚拟机和真正的计算机有什么联系和区别呢?

思考2:关于线程、进程,多任务

操作系统解决了多任务的问题,那么他是怎么解决的,常说的多进程、多线程有什么区别?

2021年3月31日,回来回答这个问题了,虽然还是查资料才懂。
概念:
进程(Process) 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。 在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。程序是指令、数据及其组织形式的描述,进程是程序的实体。

线程(thread) 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

简单地理解:
在计算机中,一个程序是一组指令的有序集合。
任务是抽象的,是一个术语,指由软件完成的一个活动,因此认为可以是线程也可以是进程(但是网上说法比较多,说任务就等于进程的人也有)。所谓多任务就是计算机看起来好像在一时间段内交替进行多个任务(进程或者线程)。
一个程序的开启就意味着一个或者多个进程被打开(由于鄙人不善编程只是一个JAVA的API爱好者,所以不知道怎么用一个程序启动多个进程,因为JAVA是启动虚拟机完成任务的所以和操作系统有关)。因此,我们还是只讨论线程和进程的关系吧。
一般来说,进程是表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。然后,把该进程放人进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才真正运行。所以,进程是系统中的并发执行的单位。
线程是进程中执行运算的最小单位。这时候你启动一个父线程让他启动三个子线程(不管他们同步不同步),那么各线程共享相同的代码和全局数据,但各有其自己的堆栈。这块全局数据的存放区就是共享内存。而进程和进程间的通讯就比较复杂了...我还不会不展开了

你可能感兴趣的:(《编码》读书笔记)