您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

计算机是怎么认识代码的

时间:2022-12-11 17:53:07  来源:简书  作者:小道萧兮

写了这么久的代码,第一次思考计算机是怎么认识自己写的代码并执行的

一个代码到底是怎么执行起来的?CPU内部到底是怎么工作的?

一、什么是二进制

大家都知道计算机是二进制,即 0 和 1,但计算机中的 0 和 1 到底是什么?

就是低电平和高电平的意思,0 代表低电平,1 代表高电平。比如 0.2V 是低电平的话,那么 5V 可能就是高电平了。一般两者都有一个阈值,当电压大于某个阈值时,即是高电平;当电平小于某个阈值时,即是低电平。计算机中的 0 和 1 是为了理解方便,给低/高电平取的别名。

同时两种称呼分别代表了数字电路和模拟电路。

数字电路是电路是以“0”和“1”及相应的逻辑符号来表示的,如下图:


数字电路

模拟电路是电路中以电压高低和电流等参数来表示的,如下图所示:


模拟电路

可以看做建筑施工图和建筑实物图的关系:数字电路主要是表现其逻辑和功能,模拟电路是搞定采用什么材料什么方式来实现数字电路想要达到的结果!

高低电平如何实现的?

二、二极管

二极管是用半导体材料(硅、硒、锗等)制成的一种电子器件,具有单向导电性。

一个二极管的实物图:


二极管

逻辑电路图(即抽象的)


二极管

电流可以从正(+)极流向负(-)极,此时处于导通状态;但反过来却不行,此时处于截止状态。这就是单向导电性!

由于单向导电性,二极管就像是一个开关:

当处于导通状态时,开关闭合,两边电压大小一致,如正极 (+) 电压为 5.2V,那么负极 (-) 也为 5.2V。
当处于截止状态时,开关断开,两边电压大小不一致,如负极(-)为 5.2V,正极 (+) 电压为 0V。

三、逻辑运算与门电路

与门

通过二极管可以获得“0”和“1”,利用这个特性,我们可以制作一些有趣的电路,比如【与门】


与门

通过小学 1 年级的知识,我们可以知道,此时 uA、uB 只要有一个是 0V,那 uY 就会和 0V 直接导通,导致 uY 也变成 0V。只有 uA、uB 都是 10V,uY 也才是10V。

并且可以把电路进行封装,不关心具体的二极管、电阻这些元器件,统一用 & 符号表示,就是上图右侧的描述。

这个装置成为【与门】,把有电压的地方计为 1,0V 电压的地方计为 0。至于具体几 V 电压,那不重要。

或门

再来分析一个或门:当输入中至少有一个“1”时,输出为“1”,若全为“0”,则输出“0”。
刚刚的与门展示的是两个输入,现在来看看四个输入!


或门

当 A、B、C、D 四个输入都是输入低电平 0 时,四个二极管都处于截止状态,此时输出即为低电平 0。
当其中任意一个不为低电平时,若A为高电平 1,此时第一个二极管导通,输出即为 A 的电平,即高电平 1。

或门在数字电路中还可以表示为:


或门

其他还有【非门】和【异或门】,跟这个都差不多。都可以用二极管或者三极管做出来,实际并不是用二极管三极管做的,因为它们太费电了。实际是用场效应管(也叫MOS管)做的。

运算离不开逻辑运算,也就是门电路,常见的逻辑运算有与、或、非、异或、同或。它们的真值表与逻辑符号如下。


逻辑电路表

四、加法器

然后我们就可以用门电路来做 CPU了。当然做 CPU 还是挺难的,我们先从简单的开始:加法器。

对于一个简单的加法器而言有两个输入(A/B)和一个输出(Sum)和一个进位(C)。

输入 A 输入 B 输出 Sum 进位 C
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

只看输入 A、B 和 输出 Sum,发现是异或门!
只看输入 A、B 和 进位 C,发现是与门!
也就是说加法器可以由异或门和与门构成!如下图所示:


半加器

到这里,我们已经做出了一个最简单的 CPU,但是现在这个只能称为“半加器”,最多只能计算 1+1,如何更进一步,比如 1+2, 2+2?

这就需要在原本的加法器增加一个进位接口,如下就是“全加器”:


全加器

两个半加器电路可以实现一个全加器。

前一个半加器将用于将 A、B 相加以产生部分和。
后一个半加器用于将 CIN 与前一个半加器产生的和相加,以获得最终的 S 输出。
任何半加器逻辑产生进位,就会有一个输出进位。因此,COUT 将是半加器进位输出。

每次都这么画实在太麻烦了,我们简化一下


全加器

将两个加法器串联在一起,就得到一个可以进行 2 位数(例如 3 + 2)的加法器。


2bit 加法器

进行 A + B 计算,例如 3 + 2 的和,3 的二进制是 11 (A1A0),2 的二进制是 10 (B1B0),

先算 A0 + B0,输出 C1 = 0,S0 = 1,再计算 A1 + B1 + C1,输出 S1 = 0,C2 = 1,最终的结果由C2、S1、S0 拼成 1012 = 5。

要几位加法就用几个加法器串联,如四位(15+15):


4bit 加法器

现在我们就有了一个 4 位加法器,已经达到了小学 2 年级的水平,是不是特别给力?

五、减法器

减法器其实是本质还是通过加法器实现的,比如 5 - 3,其实就是 5 + (-3)。

十进制 原码 反码 补码
5 0000 0101 0000 0101 0000 0101
-3 1000 0011 1111 1100 1111 1101

先将十进制转为补码,再将补码输入全加器,这样就做到了减法计算。

六、乘法器

做完加法器我们再做个乘法器吧,当然乘任意10进制数是有点麻烦的,我们先做个乘2的吧。

乘2就很简单了,对于一个2进制数数我们在后面加个 0 就算是乘 2 了,比如

5 = 101(2)
10 = 1010(2)

所以我们只要把输入都往前移动一位,再在最低位上补个零就算是乘2了。

那乘 3 呢?简单,先位移一次(乘 2)再加一次。乘 5 呢?先位移两次(乘 4)再加一次。

所以一般简单的 CPU 是没有乘法的,而乘法则是通过位移和加算的组合来通过软件来实现的。

现在假设我们有加法器了,也有一个位移1位的模块了。把这两个模块串联起来你就能算 (A + B ) * 2 了!激动人心,已经差不多到了小学 3 年级水平。

那我要是想算 A * 2 + B 呢?

简单,把加法器模块和位移模块的接线改一下就行了,改成 A 先过位移模块,再进加法器就可以了。

改个程序还得重新接线?

所以你以为呢?编程就是把线来回插啊。


编程

早期的计算机就是这样编程的,几分钟就算完了但插线好几天。而且插线是个细致且需要耐心的工作,所以那个时候的程序员都是清一色的漂亮女孩子,穿制服的那种。

七、选择器

虽然和美女作伴是个快乐的事,但插线也是个累死人的工作。所以我们需要改进一下,让 CPU 可以根据指令来相加或者乘2。


选择器

这个就简单了,sel 输入 0 则输出 i0 的数据,i0 是什么就输出什么。同理 sel 如果输入 1 则输出 i1 的数据。

有这个东西我们就可以给加法器和乘2模块(位移)设计一个激活针脚。

这个激活针脚输入 1 则激活这个模块,输入 0 则不激活。这样我们就可以控制数据是流入加法器还是位移模块了。

八、触发器

现在我们终于可以做 A × B + C 了,这就需要先保存 A×B 的结果,在与 C 相加,等等...保存?话说在计算机内部是用什么方式保存数据的呢?

由于保存数据的重要性,电路中使用何种方式可以保存数据。比如使某个器件一直输出高电平,那不就是 1 了吗?一直输入低电平,那不就是 0 了吗?这里再引入一个触发器。


触发器

这个模块的作用是存储 1bit 数据。比如上面这个,R 是 Reset,输入 1 则清零。S 是 Set,输入 1 则保存 1。RS 都输入 0 的时候,会一直输出刚才保存的内容。

注意到这个电路跟之前我们看到的都不一样了,其门电路的输出会作为自身的输入,这种结构被称为反馈电路。

我们用触发器来保存计算的中间数据(也可以是中间状态或者别的什么),1bit 肯定是不够的,不过我们可以并联,用 4 个或者 8 个来保存 4 位或者 8 位数据。这种我们称之为寄存器。

九、汇编

现在我们把上述用到的元器件组合起来,共有 8 个引脚,其中 4 个数据引脚,4 个指令引脚。数据引脚是可以输入数据,指令引脚是用来选择执行的操作。

我们定义,当指令引脚输入:
0001 读取数据,将数据引脚的数据读入寄存器;
0010 选择加法器,将数据引脚的数据与寄存器数据相加,结果在寄存器;
0100 选择乘法器,将寄存器的数据乘以数据引脚的数据,结果在寄存器;
1000 清空寄存器。

我们以一个计算题来举例:3 × 5 + 6,输入依次为:
0001 0011 # 读取数字 3
0100 0101 # 选择乘法器,乘以 5
0010 0110 # 选择加法器,加 6

不错,现在我们计算出 3 × 5 + 6,可以去小学 3 年级踢馆了,呃,不过是不是有点麻烦,这还是我们只定义了 4 种指令,要是成千上万种这谁顶得住?
我们不妨对指令稍微包装一下,规定:
0001 用 MOV 表示
0010 用 SHL 表示
0100 用 ADD 表示
并且假设现在又多了一个元件可以实现十进制到二进制的转换,那么命令应该为:
MOV 3
SHL 5
ADD 6

稍微好受一点了,这就是我们每个人都精通的汇编语言,之前仅有 0 和 1 的语言称为机器语言。

太棒了,靠这台我们设计的 CPU 可以打败所有的小学生,称霸小学校园了。而且现在我们用的是 4 位 CPU,如果换成 8 位的 CPU 完全可以吊打初中生了!

实际上用程序控制 CPU 是个挺高级的想法,再此之前计算机的 CPU 都是单独设计的。

1969 年一家日本公司 BUSICOM 想搞程序控制的计算器,而负责设计 CPU 的美国公司也觉得每次都重新设计 CPU 是个挺傻X的事,于是双方一拍即合,于1970年推出一种划时代的产品,世界上第一款微处理器4004。那家负责设计 CPU 的美国公司也一步一步成为了业界巨头。它就是 Intel。


4004

作者:小道萧兮
链接:https://www.jianshu.com/p/5985da9258c0
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


Tags:代码   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  Search: 代码  点击:(13)  评论:(0)  加入收藏
为何大语言模型不会取代码农?
译者 | 布加迪审校 | 重楼生成式人工智能(GenAI)会取代人类程序员吗?恐怕不会。不过,使用GenAI的人类可能会取代程序员。但是如今有这么多的大语言模型(LLM),实际效果不一而足。如...【详细内容】
2024-03-21  Search: 代码  点击:(24)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  Search: 代码  点击:(12)  评论:(0)  加入收藏
如何编写高性能的Java代码
作者 | 波哥审校 | 重楼在当今软件开发领域,编写高性能的Java代码是至关重要的。Java作为一种流行的编程语言,拥有强大的生态系统和丰富的工具链,但是要写出性能优异的Java代码...【详细内容】
2024-03-20  Search: 代码  点击:(24)  评论:(0)  加入收藏
微软AI程序员登场,10倍AI工程师真来了?996自主生成代码,性能超GPT-4 30%
新智元报道编辑:桃子 润【新智元导读】全球首个AI程序员Devin诞生之后,让码农纷纷恐慌。没想到,微软同时也整出了一个AI程序员——AutoDev,能够自主生成、执行代码等...【详细内容】
2024-03-18  Search: 代码  点击:(20)  评论:(0)  加入收藏
对JavaScript代码压缩有什么好处?
对JavaScript代码进行压缩主要带来以下好处: 减小文件大小:通过移除代码中的空白符、换行符、注释,以及缩短变量名等方式,可以显著减小JavaScript文件的大小。这有助于减少网页...【详细内容】
2024-03-13  Search: 代码  点击:(2)  评论:(0)  加入收藏
如何进行Python代码的代码重构和优化?
Python是一种高级编程语言,它具有简洁、易于理解和易于维护的特点。然而,代码重构和优化对于保持代码质量和性能至关重要。什么是代码重构?代码重构是指在不改变代码外部行为的...【详细内容】
2024-02-22  Search: 代码  点击:(36)  评论:(0)  加入收藏
18个JavaScript技巧:编写简洁高效的代码
本文翻译自 18 JavaScript Tips : You Should Know for Clean and Efficient Code,作者:Shefali, 略有删改。在这篇文章中,我将分享18个JavaScript技巧,以及一些你应该知道的示例...【详细内容】
2024-01-30  Search: 代码  点击:(71)  评论:(0)  加入收藏
C++代码优化攻略
今天我们将深入探讨C++性能优化的世界。在当今软件开发的浪潮中,高性能的代码是必不可少的。无论是开发桌面应用、移动应用,还是嵌入式系统,性能都是关键。1. 选择合适的数据结...【详细内容】
2024-01-26  Search: 代码  点击:(117)  评论:(0)  加入收藏
手把手教你为开源项目贡献代码
背景前段时间无意间看到一篇公众号 招贤令:一起来搞一个新开源项目,作者介绍他想要做一个开源项目:cprobe 用于整合目前市面上散落在各地的 Exporter,统一进行管理。比如我们常...【详细内容】
2024-01-26  Search: 代码  点击:(71)  评论:(0)  加入收藏
▌简易百科推荐
Netflix 是如何管理 2.38 亿会员的
作者 | Surabhi Diwan译者 | 明知山策划 | TinaNetflix 高级软件工程师 Surabhi Diwan 在 2023 年旧金山 QCon 大会上发表了题为管理 Netflix 的 2.38 亿会员 的演讲。她在...【详细内容】
2024-04-08    InfoQ  Tags:Netflix   点击:(2)  评论:(0)  加入收藏
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(7)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(13)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(9)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(11)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(9)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
站内最新
站内热门
站内头条