深入浅出计算机组成原理
徐文浩
bothub创始人
立即订阅
13019 人已学习
课程目录
已完结 62 讲
0/4登录后,你可以任选4讲全文学习。
入门篇 (5讲)
开篇词 | 为什么你需要学习计算机组成原理?
免费
01 | 冯·诺依曼体系结构:计算机组成的金字塔
02 | 给你一张知识地图,计算机组成原理应该这么学
03 | 通过你的CPU主频,我们来谈谈“性能”究竟是什么?
04 | 穿越功耗墙,我们该从哪些方面提升“性能”?
原理篇:指令和运算 (12讲)
05 | 计算机指令:让我们试试用纸带编程
06 | 指令跳转:原来if...else就是goto
07 | 函数调用:为什么会发生stack overflow?
08 | ELF和静态链接:为什么程序无法同时在Linux和Windows下运行?
09 | 程序装载:“640K内存”真的不够用么?
10 | 动态链接:程序内部的“共享单车”
11 | 二进制编码:“手持两把锟斤拷,口中疾呼烫烫烫”?
12 | 理解电路:从电报机到门电路,我们如何做到“千里传信”?
13 | 加法器:如何像搭乐高一样搭电路(上)?
14 | 乘法器:如何像搭乐高一样搭电路(下)?
15 | 浮点数和定点数(上):怎么用有限的Bit表示尽可能多的信息?
16 | 浮点数和定点数(下):深入理解浮点数到底有什么用?
原理篇:处理器 (18讲)
17 | 建立数据通路(上):指令+运算=CPU
18 | 建立数据通路(中):指令+运算=CPU
19 | 建立数据通路(下):指令+运算=CPU
20 | 面向流水线的指令设计(上):一心多用的现代CPU
21 | 面向流水线的指令设计(下):奔腾4是怎么失败的?
22 | 冒险和预测(一):hazard是“危”也是“机”
23 | 冒险和预测(二):流水线里的接力赛
24 | 冒险和预测(三):CPU里的“线程池”
25 | 冒险和预测(四):今天下雨了,明天还会下雨么?
26 | Superscalar和VLIW:如何让CPU的吞吐率超过1?
27 | SIMD:如何加速矩阵乘法?
28 | 异常和中断:程序出错了怎么办?
29 | CISC和RISC:为什么手机芯片都是ARM?
30 | GPU(上):为什么玩游戏需要使用GPU?
31 | GPU(下):为什么深度学习需要使用GPU?
32 | FPGA和ASIC:计算机体系结构的黄金时代
33 | 解读TPU:设计和拆解一块ASIC芯片
34 | 理解虚拟机:你在云上拿到的计算机是什么样的?
原理篇:存储与I/O系统 (17讲)
35 | 存储器层次结构全景:数据存储的大金字塔长什么样?
36 | 局部性原理:数据库性能跟不上,加个缓存就好了?
37 | 高速缓存(上):“4毫秒”究竟值多少钱?
38 | 高速缓存(下):你确定你的数据更新了么?
39 | MESI协议:如何让多核CPU的高速缓存保持一致?
40 | 理解内存(上):虚拟内存和内存保护是什么?
41 | 理解内存(下):解析TLB和内存保护
42 | 总线:计算机内部的高速公路
43 | 输入输出设备:我们并不是只能用灯泡显示“0”和“1”
44 | 理解IO_WAIT:I/O性能到底是怎么回事儿?
45 | 机械硬盘:Google早期用过的“黑科技”
46 | SSD硬盘(上):如何完成性能优化的KPI?
47 | SSD硬盘(下):如何完成性能优化的KPI?
48 | DMA:为什么Kafka这么快?
49 | 数据完整性(上):硬件坏了怎么办?
50 | 数据完整性(下):如何还原犯罪现场?
51 | 分布式计算:如果所有人的大脑都联网会怎样?
应用篇 (5讲)
52 | 设计大型DMP系统(上):MongoDB并不是什么灵丹妙药
53 | 设计大型DMP系统(下):SSD拯救了所有的DBA
54 | 理解Disruptor(上):带你体会CPU高速缓存的风驰电掣
55 | 理解Disruptor(下):不需要换挡和踩刹车的CPU,有多快?
结束语 | 知也无涯,愿你也享受发现的乐趣
免费
答疑与加餐 (5讲)
特别加餐 | 我在2019年F8大会的两日见闻录
FAQ第一期 | 学与不学,知识就在那里,不如就先学好了
用户故事 | 赵文海:怕什么真理无穷,进一寸有一寸的欢喜
FAQ第二期 | 世界上第一个编程语言是怎么来的?
特别加餐 | 我的一天怎么过?
深入浅出计算机组成原理
登录|注册

13 | 加法器:如何像搭乐高一样搭电路(上)?

徐文浩 2019-05-24
上一讲,我们看到了如何通过电路,在计算机硬件层面设计最基本的单元,门电路。我给你看的门电路非常简单,只能做简单的 “与(AND)”“或(OR)”“NOT(非)”和“异或(XOR)”,这样最基本的单比特逻辑运算。下面这些门电路的标识,你需要非常熟悉,后续的电路都是由这些门电路组合起来的。
这些基本的门电路,是我们计算机硬件端的最基本的“积木”,就好像乐高积木里面最简单的小方块。看似不起眼,但是把它们组合起来,最终可以搭出一个星球大战里面千年隼这样的大玩意儿。我们今天包含十亿级别晶体管的现代 CPU,都是由这样一个一个的门电路组合而成的。

异或门和半加器

我们看到的基础门电路,输入都是两个单独的 bit,输出是一个单独的 bit。如果我们要对 2 个 8 位(bit)的数,计算与、或、非这样的简单逻辑运算,其实很容易。只要连续摆放 8 个开关,来代表一个 8 位数。这样的两组开关,从左到右,上下单个的位开关之间,都统一用“与门”或者“或门”连起来,就是两个 8 位数的 AND 或者 OR 的运算了。
比起 AND 或者 OR 这样的电路外,要想实现整数的加法,就需要组建稍微复杂一点儿的电路了。
我们先回归一个最简单的 8 位的无符号整数的加法。这里的“无符号”,表示我们并不需要使用补码来表示负数。无论高位是“0”还是“1”,这个整数都是一个正数。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入浅出计算机组成原理》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(31)

  • 不记年
    基本电路>门电路>全加器>加法器,经历了三层的封装,分层可以带来很多好处,但经过这么多层的封装是不是也带来了性能的损耗,所以我想对于像加法器这样经常用到的电路,可不可以打破分层,直接通过最底层的电路来实现,以达到性能的最优呢。在进一步,性能和封装之间是否也存在着取舍呢

    作者回复: 不记年同学你好,

    你的思考很对,实际的加法器,并不是由全加器串联组成的,在14讲里面我们可以看到为了减少门延迟的损失,实际高位的计算结果直接来自低位的组合电路里面的输入。

    封装意味着我们提供了更多的“简单电路”或者说“简单指令”来操作。但这也意味着同样复杂的操作需要更多条指令。

    这个也是为什么在计算机体系结构里面会有 RISC 和 CISC 这样的复杂/精简 指令之争。

    2019-05-27
    8
  • 一步
    我们仍然是从左到右,一位一位进行计算,只是把从逢 10 进 1 变成逢 2 进 1。

    这里不应该是从右往左运算吗?

    作者回复: 一步同学你好,

    谢谢指出,的确是从右到左计算,我修改一下。

    2019-05-24
    7
  • 张立昊Leon
    负数用补码表示的话加法就和正数的加法没什么区别了,只是结果如果是负数的话,也是补码。发生溢出会有问题,最高位符号有可能会变,需要额外的标记位

    作者回复: 👍

    2019-05-26
    5
  • 陈华应
    打卡,5月24日03:45,坚持完整的学到底~

    作者回复: 加油

    2019-05-24
    5
  • 俊釆
    全加器图中没有U,这个是其他地方的进位信号?
    2019-06-04
    1
    4
  • kdb_reboot
    这部分就是本科学的数电了

    作者回复: 👍

    2019-05-26
    4
  • ldd
    课后思考:
    补码表示下,加法器也是可以正常运行的;因为补码的发明就是为了方便正负数的二进制计算。
    正数+负数是不会溢出的,所以加法器可以直接忽略最左边的进位;
    但是补码计算,还是会出现溢出的情况的,比如:假设二进制位数是4位,-8-2=6;7+2=-1 就算是溢出了;
    那么还是需要最右边的输出来判断是否溢出的:
    假设最右边的输入为a、b,输出为c,那么溢出位可以为 (~(a&b)) & c & (~(a&b)),输出为1,就代表溢出了,否则就是未溢出。

    不知道思考的对不对,有不对的地方,望老师指出。

    作者回复: 我不知道我有没有准确理解你的意思

    两个负数相加,是否溢出,其实不是看最后多出来的进位的信号。而是也要看计算结果的最高位是1还是0
    如果两个输入的高位是1而输出的高位是0,那么就溢出了,如果输出的高位还是1就没有溢出。

    你这里的a,b,c是不是指输入a,b和输出c的左侧的高位(不是进位的溢出位)?我的理解没有错吧?

    2019-05-27
    3
  • Knight²º¹⁸
    解答了我多年的疑惑
    2019-05-24
    3
  • 铁皮
    课后思考题:
    用补码表示的话,这个加法器应该可以实现正数加负数。
    最左端如有溢出位的情况去掉就可以

    作者回复: 是的,不过可以思考一下两个负数的相加或者整数的相加是否也会溢出?怎么通过电路来告诉大家是发生了溢出?

    2019-05-24
    2
  • cc
    我们把两个半加器的进位输出,作为一个或门的输入连接起来,只要两次加法中任何一次需要进位,那么在二位上,我们就会向左侧的四位进一位。

    老师,这块没看懂。为什么任何一次需要进位,我们都要向四位进位呢?比如两个数分别是01和01,这样其实不用向四位进位的

    作者回复: cc同学你好

    的确不是每个计算都需要进位,但是我们的电路必须准备好可能发生进位。

    而进位的时候,可能来自当前位两个1的相加会发生进位。
    但还有一种可能,就是当前位只有一个1,但是从更低位又进位来了一个1,这样也需要向高位进行进位。

    2019-05-24
    2
  • 玉琢天窗
    老师,要想自己搭建一个电路实现1+1,需要哪些材料呢

    作者回复: 如果是写程序模拟的话有很多办法,比如有人用Minecraft 做了一个虚拟的CPU http://mc.163.com/2017/04/07/25535_682214.html

    如果是硬件,如果只是为了体验,最简单的办法是用电路绘画导电笔直接在纸上画了来体验一下

    或者也可以去淘宝上买个组合电路套件自己来搭一下。

    2019-09-11
    1
    1
  • DreamItPossible
    使用全加器可以实现使用补码表示的有符号数,正数加负数转换成正数加上这个负数的补码即可。
    如何检测溢出?
    首先,列举下两个有符号数相加产生溢出的条件:
    - 正数+正数
    如果结果为负数,则产生了溢出;
    - 负数+负数
    如果结果为正数,则产生了溢出;
    - 正数-负数
    如果结果为负数,则产生了溢出;
    - 负数-正数
    如果结果为正数,则产生了溢出;

    其次,可以根据最高数值位是否产生进位,以及符号位是否产生进位来判断是否有溢出发生,对应上面的四种情况就是:
    - 正数+正数有溢出,即最高数值位产生了进位,而符号位没有进位;
    - 负数+负数有溢出,即最高数值位没有产生进位,而符号位产生了进位;
    - 正数-负数有溢出,即最高数值位产生了进位,而符号位没有进位;
    - 负数-正数有溢出,即最高数值位没有产生进位,而符号位产生了进位;
    2019-08-13
    1
  • Dashing
    看次高位进位与最高位进位,异或,为1溢出,为0,没有益处
    2019-08-07
    1
  • supermouse
    老师您好!请问「与非门」、「或非门」是将「与门」、「或门」计算得到的结果取反吗?

    作者回复: 是的,就是把与门和或门的真值表取反

    2019-05-26
    1
  • 冰激凌的眼泪
    突破1,两个输入,两个输出,简单门电路是两个输入一个输出
    突破2,三个输入,两个输出
    上面是加法器实现的基础
    简单门电路实现了半加器,进而利用半加器实现了全加器
    语句实现了简单函数,进而可以形成复杂函数
    2019-05-25
    1
  • Ant
    老师 图片 mp3等占用空间比较大的文件 编译的时候放在哪里阿

    作者回复: 一般情况下,这些是“数据”而不是“程序”,会放在单独的数据文件里面,在编译的过程中并不会用到。

    2019-05-24
    1
  • 小海海
    思考题: 反向推导,补码的设计本来就是要解决正数加负数的问题,使之可以当作普通的加法来进位即可,所以文章里的加法器模型应该是可以的

    作者回复: 回答正确,不过可以再想想补码情况下,如何处理溢出呢?

    2019-05-24
    1
  • 靠人品去赢
    这个加法器的组成,让我知道想通了int这些基本类型的范围具体是怎么回事(就给你16个全加器组成,结果溢出了超过16位,自然就超出int类型范围)。
    那想问一下,栈溢出,空指针这些日常喜闻乐见的是怎么回事,计算机怎么判定的呢。

    作者回复: 栈溢出我们在前面讲stackoverflow已经讲过啦,可以去看第7讲。

    空指针,其实也很容易里面,我们期望在某个数据里面放上一个内存地址,但是并没有真实设置对应的值,那么里面要么是对应内存初始状态,可能就是一个错误的地址,会导致程序出错呀。

    2019-05-24
    1
  • 活的潇洒
    今天提前一个半小时到单位,就是为了早点听音频做笔记,坚持完整的学到底,坚持完整的笔记到底
    day13 学习笔记:https://www.cnblogs.com/luoahong/p/10916066.html
    2019-05-24
    1
  • 拯救地球好累
    ---总结---
    封装及模块化:计算机硬件或软件设计中,为了能提高可重用性和为上层开发人员屏蔽下层细节,往往会提供包装好的模块并划分一定的层次。但通用系统的效率往往会低于专用系统,因此在提高开发效率的同时往往也会有一定的性能损失,在其他层面无法取得性能优化的突破且有性能方面的需求时,可以从该方面考虑。
    最简单的门电路:与门、或门、非门、异或门、与非门、或非门
    半加器:异或门(做加法)+与门(判进位)
    全加器:两个半加器(结合进位信号做加法)+或门(产生进位信号)
    2019-10-26
收起评论
31
返回
顶部