本文接上文程序是如何在计算机上被执行的?(上篇:软件部分),主要内容是机器语言如何在计算机硬件上运行,关于逻辑门,加法器,布尔运算,亦即,cpu的工作原理

1、逻辑门

以下图片是《三体》中的一个情节:

这段故事提到一千万个这样的门部件,就是搭建计算机的基础元件,逻辑门

那什么是与、或、非呢?

相信聪明的你高中物理有学过电路,想象三种场景:

1、非门开关控制灯泡,1是打开,0是关闭

2、与门
串连电路,只要关一个开关,灯泡就不亮,只有两个开关都打开灯泡才亮,即必须都是1才亮。

3、或门

并联电路,只要有一个开关是开的,灯泡就亮。

道生一,一生二,二生三,三生万物,就像人体蛋白质由二十种氨基酸通过不同组合而成,使用这三种基本逻辑门,就可以实现所有逻辑运算,进而构造出一整套的计算,这时候我们认为,与、或、非就是逻辑完备的。

一切运算的基础——加法

现在能生成万物的基础元素与或非门出现了,接下来我们着手设计CPU最重要的能力:计算,以加法为例。由于CPU只认识0和1,也就是二进制,那么二进制的加法有哪些组合呢:

  • 0+0,结果为0,进位为0

  • 0+1,结果为1,进位为0

  • 1+0,结果为1,进位为0

  • 1+1,结果为0,进位为1,二进制嘛!

注意进位一列,只有当两路输入的值都是1时,进位才是1,看一下你设计的三种组合电路,这就是与门啊,有没有!

但,只有计算能力是不够的,电路需要能记得住信息。

神奇的记忆能力

到目前为止,你设计的组合电路比如加法器天生是没有办法存储信息的,它们只是简单的根据输入得出输出,但输入输出总的有个地方能够保存起来,这就是需要电路能保存信息。

电路怎么能保存信息呢?一位英国物理学家,设计了这样一个简单但极其神奇的电路:

这是两个NAND门的组合,不要紧张,NAND也是有你设计的与或非门组合而成的,所谓NAND门就是与非门,先与然后取非,比如给定输入1和0,那么与运算后为0,非运算后为1,这就是与非门,这些不重要。

比较独特的是该电路的组合方式,一个NAND门的输出是两一个NAND门的输入,该电路的组合方式会自带一种很有趣的特性,只要给S和R段输入1,那么这个电路只会有两种状态:

要么a端为1,此时B=0、A=1、b=0;

要么a端为0,此时B=1、A=0、b=1;

不会再有其他可能了,我们把a端的值作为电路的输出。

此后,你把S端置为0的话(R保持为1),那么电路的输出也就是a端永远为1,这时就可以说我们把1存到电路中了;而如果你把R段置为0的话(S保持为1),那么此时电路的输出也就是a端永远为0,此时我们可以说把0存到电路中了。

就问你神奇不神奇,电路竟然具备存储信息的能力了。现在为保存信息你需要同时设置S端和R端,但你的输入是有一个(存储一个bit位嘛),为此你对电路进行了简单的改造:

这样,当D为0时,整个电路保存的就是0,否则就是1。

同理,我们可以通过任意加法器进行组合拼接实现较长的二进制计算。实际上,数学家已经证明,加法是实现所有数学运算的基础。有了加法器,原则上就可以通过他们搭建任何其他计算,像乘法、除法、平方、开方、三角函数等。而伟大的计算机科学家图灵在一百年前就已经指明,这些简单运算足以支撑任何信息处理的过程。

寄存器与内存的诞生

现在你的电路能存储一个比特位了,想存储多个比特位还不简单,复制粘贴就可以了:

我们管这个组合电路就叫寄存器,你没有看错,我们常说的寄存器就是这个东西,类似于平常运算过程用到的可擦写草稿纸。

上图左侧是十六进制操作码,右边是将数据从一个寄存器复制到另一个寄存器的操作。

你不满足,还要继续搭建更加复杂的电路以存储更多信息,同时提供寻址功能,就这样内存也诞生了。

寄存器及内存都离不开上一节那个简单电路,只要通电,这个电路中就保存信息,但是断电后很显然保存的信息就丢掉了,现在你应该明白为什么内存在断电后就不能保存数据了吧。

以上就是cpu计算的原理了,如前所述,真正的计算机在运行的时候,是通过逐条读取存放在内存中的相应指令,然后进行计算和操作实现的。被机器所识别并运行的机器指令或操作指令,会被编码成方便人类理解的筑基形式,就是汇编语言

再接上一篇文章程序是如何在计算机上被执行的?(上篇:软件部分),从后往前读,就是整个程序在计算机上执行的流程了。

总结:

回顾一下,编程语言是经过如下流程在计算机上执行的:

编程语言---语法分析、词法分析---转换成汇编语言---机器指令---cpu运行---逻辑门---与或非

这样看,所有语言,不管是js,python,go还是其他的,最终都会被解析成汇编语言在cpu上执行。那么,所有语言,都是等价的,所有语言都可以通过编译器实现从一种语言到另一种语言到转换

当计算机运行程序时,我们会发现每一层表现形式不一样,但本质都是计算,而且每一层都是建立在下一层基础上的抽象。虽然分了很多层,所有层都是等价的,层和层之间有明确边界,越到下层牵涉到的基础单元越多,越到上层越简洁。

抽象对我们在计算机科学中做的每件事都很有帮助。抽象使得编写一个大型程序成为可能,将其划分为小而且容易理解的部分,用C这样的高级语言编写这样的程序不用考虑汇编,用汇编写代码不用考虑逻辑门,用逻辑门来构建处理器不用太多考虑晶体管,抽象是如此重要

不管是计算机网络分层原理,计算机系统,应用…都有抽象,都是为了让使用者更易用更好用,至此,理解了cpu,理解了语言的解析和执行、理解了分层和抽象,完。

程序是如何在计算机上被执行的?(下篇:cpu工作原理)的更多相关文章

  1. 优秀Java程序员必须了解的GC工作原理(转)

    一个优秀的Java程序员必须了解GC(Garbage Collection 垃圾收集)的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系 ...

  2. 安装程序不能验证Update.inf文件的完整性,请确定加密服务正在此计算机上执行

    近期安装Microsoft .NET Framework 4(独立安装程序)时,提示"安装程序不能验证Update.inf文件的完整性,请确定加密服务正在此计算机上执行" 没法放狗 ...

  3. 未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序

    这种错误的可能性有几种,比如: 1.没有安装数据访问组件,需要安装相应版本的数据访问组件: 2.没有安装相应版本的Office客户端,需要安装相应版本的Office客户端: 3.Microsoft.J ...

  4. 未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序 解决方法

    最近在搞asp.net.今天在做数据库操作的时候,老发生错误,还以为是自己代码有问题,检查了好久都发现错误. 错误提示: 未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程 ...

  5. 未在本地计算机上注册"microsoft.ACE.oledb.12.0"提供程序解决办法

    错误信息:未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序. 解决办法: 去http://download.microsoft.com/download/7/0/3/7 ...

  6. 未在本地计算机上注册“OraOLEDB.Oracle.1”提供程序解决方案

    未在本地计算机上注册“OraOLEDB.Oracle.1”提供程序解决方案 一.现象:  C#程序中需要以Provider=OraOLEDB.Oracle.1方式访问ORACLE数据库.但程序执行时报 ...

  7. asp.net采用OLEDB方式导入Excel数据时提示:未在本地计算机上注册"Microsoft.Jet.OLEDB.4.0" 提供程序"

    笔者在项目中做做了一个从Excel表格中导入数据的模块.大体上asp.net项目中导入Excel大体分成三类: 1)采用c#内置方案System.Data.OleDb(限制较小, 通用) 2)采用Ex ...

  8. IIS7.5 提示未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序

    在WIN7 X64平台IIS7.5,使用Asp.net连接access数据库时候,提示:未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序. 说明: 执行当前 Web 请求 ...

  9. 从Excel中导入数据时,提示“未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序”的解决办法

    注意,64位系统,用64位的补丁文件; https://www.cnblogs.com/A2008A/articles/2438962.html 操作系统:使用的是64位的Windows Server ...

  10. 本地计算机上的MySQL服务启动后停止。某些服务在未由其他服务或程序使用时将自动

    重新安装MySQL数据库,由于安装的时候马虎,一路next(事实上,某些地方需要严格的配置,我忘记注意了),导致现在出了很多麻烦. 错误信息: 本地计算机上的MySQL服务启动后停止.某些服务在未由其 ...

随机推荐

  1. 【Springboot】项目启动后执行特定方法

    Springboot项目启动后执行特定方法 Springboot给我们提供了两种"开机启动"方式:ApplicationRunner和CommandLineRunner. 这两种方 ...

  2. 学习jQuery核心内容这一篇就够了

    jQuery 1. 介绍 jQuery是JavaScript的工具库,对原生JavaScript中的DOM操作.事件处理.数据处理等进行封装,提供更便捷的方法. 让我们用更少的代码完成我们的js操作 ...

  3. 如何使用C#中的Lambda表达式操作Redis Hash结构,简化缓存中对象属性的读写操作

    Redis是一个开源的.高性能的.基于内存的键值数据库,它支持多种数据结构,如字符串.列表.集合.散列.有序集合等.其中,Redis的散列(Hash)结构是一个常用的结构,今天跟大家分享一个我的日常操 ...

  4. 并发编程-CompletableFuture解析

    1.CompletableFuture介绍 CompletableFuture对象是JDK1.8版本新引入的类,这个类实现了两个接口,一个是Future接口,一个是CompletionStage接口. ...

  5. rman catalog 遇到的一个错误

    [oracle@source admin]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.3.0 Production on Thu Jun 22 09: ...

  6. 堆 Heap & 栈 Stack(.Net)【概念解析系列_3】【C# 基础】

    〇.前言 本文主要围绕 .Net 框架中的托管堆(Heap,简称堆)和堆栈(Stack,简称栈)展开. .Net 程序在 CLR(Common Language Runtime 公共语言运行时)上运行 ...

  7. Vue3 中 keepAlive 如何搭配 VueRouter 来更自由的控制页面的状态缓存?

    在 vue 中,默认情况下,一个组件实例在被替换掉后会被销毁.这会导致它丢失其中所有已变化的状态--当这个组件再一次被显示时,会创建一个只带有初始状态的新实例.但是 vue 提供了 keep-aliv ...

  8. Go 并发编程 - Goroutine 基础 (一)

    基础概念 进程与线程 进程是一次程序在操作系统执行的过程,需要消耗一定的CPU.时间.内存.IO等.每个进程都拥有着独立的内存空间和系统资源.进程之间的内存是不共享的.通常需要使用 IPC 机制进行数 ...

  9. 一台服务器上部署 Redis 伪集群

    哈喽大家好,我是咸鱼 今天这篇文章介绍如何在一台服务器(以 CentOS 7.9 为例)上通过 redis-trib.rb 工具搭建 Redis cluster (三主三从) redis-trib.r ...

  10. SQL取上一条, 下一条记录方法

    如果我们需要取id为3的前后的1条记录.  就可以用以下方法 取上一条记录: select  *  from `表名` where `id`<3 order by `id` desc limit ...