当前位置: 首页 > news >正文

《编码——隐匿在计算机软硬件背后的语言》精炼——第17章(自动操作)

夫道成于学而藏于书,学进于振而废于穷。

文章目录

  • 完善加法器
  • 加入代码的加法器
  • 扩大加数范围
  • 自由调用地址的加法器
  • 合并代码RAM和数据RAM
  • Jump指令
    • 硬件实现
    • 条件Jump指令
      • 零转移的硬件实现
      • 条件Jump指令的例子
  • 总结

完善加法器

我们在第14章介绍了一个可以进行连加的加法器,接下来我们对它进行扩展:
在这里插入图片描述
我们将数据用之前讲到的RAM进行存储,以达到回看这些数据的效果。在这里插入图片描述
振荡器和16位计数器连接起来既可以计时,又可以计数,这也是上一篇文章讲过的。在这里,我们用它来计数,通过顺序存储所需要的数据,我们做到将RAM中的数据依次加入加法器中进行相加。

十六位计数器从0000h开始,每隔一段时间输出+1,一直到FFFFh。那么只要从0000h开始存储数据就可以了。

通过同步时钟(Clk),可以保证完成一个完整的加法过程;当摁下清零开关(Clr)时,锁存器和计数器同时清零,重新从第一个数开始计算。
我们也可以把计算结果直接写回到RAM中,这样虽然将原来的加数覆盖掉了,但胜在省掉了灯泡。
在这里插入图片描述
接下来,我们将进入另一个阶段的完善。

加入代码的加法器

上面的加法器有一个明显的缺点,就是它的加法过程一旦开始,便不能再结束,计数器到FFFFh后会回到0000h重新计数。因此我们需要进行改进,即引入代码,让它能够自动执行额外的操作。
我们用例子说明这些代码是怎样加到装置中去且在装置中发挥作用的。假设我们先对三个数相加,再对两个数相加,再对三个数相加,那么只用上图装置可以表示为:
在这里插入图片描述
最左边是地址,表格中是存储的具体数值,最右边是说明。我们用这种形式来表示加入代码后加法器的操作。
首先思考一下我们暂时需要什么样的操作。下表是我们现在需要的操作:
在这里插入图片描述

  1. Load:将RAM中的数加载到加法器中作为第一个加数。
  2. Store:将锁存器中的数存储到RAM中。
  3. Add:将RAM中的数加载到加法器中与之前的数相加。
  4. Halt:停止所有操作。

思考一下Load操作和Add操作的区别。Load操作不需要将锁存器中的结果存到加法器中,但Add操作需要。
这样的话,我们就能表示在上面的例子中,我们需要进行什么样的操作:
在这里插入图片描述

要实现这些操作,我们需要再加上一些硬件。第一,我们需要加入一个存储代码的RAM,它和存储数据的RAM一起同时被计数器控制,称为代码RAM阵列;第二,执行Load指令时,锁存器的输入直接从数据RAM阵列中得到,而执行Add指令时,则从加法器中得到,这样的话就需要加入一个2-1选择器。具体如下所示:
在这里插入图片描述
我们可以通过输出不同的代码来控制电路中的控制信号,这可以通过加入一些逻辑门实现,这里省略。
接下来,再次完善代码,我们加入减法:
在这里插入图片描述
这里减法的代码是21h,与加法代码只在最后一位不同。检测到这个不同后,将从数据RAM阵列中取出的数进行取反。如下图所示,在该图中,减法与加法不同的位称为C0
在这里插入图片描述
其他操作的问题暂时解决,接下来我们将扩展加数的范围,将它们从8位扩展到16位。

扩大加数范围

我们的目标是不改动加法器的位数,使装置能进行16位加数的运算。很容易想到,我们将16位的数分成两半,先将低字节相加,再将高字节相加即可:
在这里插入图片描述
结果的低字节存储在0002h,高字节存储在0005h。
接下来,我们需要解决进位的问题。这个问题实际上在前面已经解决,只需要存储一个信号作为进位就可以了,用一位存储器来存储即可。
加入进位信号存储器后,原来的Add代码就不能完全进行自动操作了,我们需要再引入一个专门用于进位情况的代码,就称作Add with Carry(进位加法)。在执行Add操作时,我们将最高位的进位输出存储到一位存储器中;在进行16位的高字节数相加时,我们使用进位加法代码,它将进位存储器中的信号也当作加数一起在加法器内相加。进行16位的减法运算时,这个存储器也可以存储对高字节的借位,可以再引入一个代码Subtract with Borrow(借位减法)进行操作。
加入Add with Carry和Subtract with Borrow后,我们的代码如下所示:
在这里插入图片描述
注意,当进行16位加法高字节运算时,我们一般都使用进位加法进行运算。减法同理。

自由调用地址的加法器

我们通过扩展指令的方式,将要调用的地址单独编码在指令RAM而非直接用计数器指明地址,这样就可以实现对地址的自由调用。具体实现方案如下所示:
在这里插入图片描述
16位计数器连接代码RAM阵列,在代码RAM中依次取出代码。将每个代码扩展为三个字节,第一个字节指明执行什么操作,余下两个字节指明调用数据RAM的16位地址。
由于计数器依次前进1,因此一个指令需要三个时钟周期,而一个完整的指令周期需要四个时钟周期,因此需要更为复杂的控制信号,这里省略。不论如何,这个加法器的速度只有原来的1/4,但是它拥有更完善的功能。

合并代码RAM和数据RAM

事实上,我们可以将这两个RAM合为一个。例如,如果我们有一个指令为10h 32h 52h。不难解释这个指令:加载3252h处的数据到加法器中。正常情况下,我们会用后两个字节在数据RAM的3252h处找到数据。但如果我们将3252h处的数据也存入代码RAM的3252h处,我们就可以省略掉数据RAM而用代码RAM来同时存储代码和数据。实现如下:
在这里插入图片描述
我们先选择计数器作为2-1选择器的输出,从RAM中取出代码,代码的后两个字节被锁存器保存后折回作为2-1选择器的第二个输出(32h,52h),这样就能从RAM中取出3252h处的数据,这个数据最后从右上角输出到加法器中。我们用FFh(Halt指令)来分割存储代码的区域和存储数据的区域。

Jump指令

还存在一个问题是,如果我们还想要重新写入更多的指令,我们就必须用其他指令替换掉Halt指令,但这样的话,我们就可能把原本是数据的区域当成存储代码的区域。为了解决这个问题,我们引入一个新的Jump指令,这个指令可以指定下一次执行的指令地址而不一定必须顺序执行。有了这个指令,就不需要用Halt指令来分割区域了。将这个指令加入指令表;
在这里插入图片描述
Jump指令后面跟一个16位的数,表示要跳转的地址。

硬件实现

不难想到,Jump指令通过控制16位计数器来实现其功能。进一步讲,它通过控制Pre和Clr信号来控制计数器的输出。Pre信号强制Q=1,Clr信号强制Q=0。我们新增的电路如下:
在这里插入图片描述

  • 置位信号为0,复位信号为0时,三个门的输出都为0,A无法控制Pre和Clr信号。
  • 置位信号为0,复位信号为1时,Pre信号为0,Clr信号为1,A无法控制Pre和Clr信号
  • 置位信号为1,复位信号为0时,设A信号为a,则Pre信号输入为a,Clr信号输入为¬a,计数器的输出取决于A输入,达到Jump指令的目的
  • 置位信号为1,复位信号为1的情况不合法

在实际电路中,由于只增加了A信号和置位输入,且A信号输入来源于RAM阵列中Jump指令的操作数,置位信号遇到30h(Jump指令操作数)时就设为1,因此对电路改动不是很大:
在这里插入图片描述

条件Jump指令

在有些情况下,我们需要达到一些条件时再进行Jump指令,这需要引入条件Jump指令。下面是引入条件Jump指令后的指令表:
在这里插入图片描述
我们可以看到,在指令表中,我们一共有四个标准:零,非零,进位,非进位。其中进位很好理解,当进位锁存器输出值满足要求时进行Jump指令。对于零转移(非零转移)来说,当加法器最后一次相加得到的值为0(不为0)的时候,我们执行Jump指令。

零转移的硬件实现

为了实现零转移和非零转移,我们需要新增一个零锁存器:
在这里插入图片描述
当加减相关的四条指令被执行时,锁存器进行锁存最后的结果并输出到零标志位,根据零标志位,决定是否执行Jump指令。

条件Jump指令的例子

下面是一个用到条件Jump指令的例子:执行相乘A7h和1Ch运算。
很容易想到将A7h相加28(1Ch)遍即可,循环相加利用Jump指令很好实现,如果想要控制相加遍数,那么利用非零转移指令即可。用某种方式存储1Ch,每一次相加后将1Ch减1,未减到0时,Jump指令使循环相加过程继续;减到0时,Jump指令不执行,直接结束。
下面是实际实现的指令序列:
在这里插入图片描述
这一部分存储了乘数、被乘数和结果要保存的地方。
在这里插入图片描述
这一部分执行相加运算,将上一次相加的结果再次与被乘数相加。
在这里插入图片描述
这一部分是重点,包含了五条指令。在前三条指令中,我们将乘数与FFh相加。注意,这里的FFh被看作一个数,乘数和FFh相加就相当于将乘数减1.第四条指令是条件Jump指令,它对当前加法器的输出,即乘数的当前值进行检测,如果乘数不为0,那么Jump指令执行,回到加法部分继续进行相加运算;如果乘数为0,说明加法过程已经进行28遍,Jump指令不再调用,直接执行FFh,即Halt指令。

总结

到这里,我们已经完成了一个计算机应有的功能,通过这些简单的指令,我们可以做到各种运算:乘除法,平方,开根……计算机也就此诞生。
请添加图片描述
我是霜_哀,在算法之路上努力前行的一位萌新,感谢你的阅读!如果觉得好的话,可以关注一下,我会在将来带来更多更全面的知识讲解!

相关文章:

《编码——隐匿在计算机软硬件背后的语言》精炼——第17章(自动操作)

夫道成于学而藏于书,学进于振而废于穷。 文章目录 完善加法器加入代码的加法器扩大加数范围自由调用地址的加法器合并代码RAM和数据RAMJump指令硬件实现条件Jump指令零转移的硬件实现条件Jump指令的例子 总结 完善加法器 我们在第14章介绍了一个可以进行连加的加法…...

用Colab免费部署AI绘画云平台Stable Diffusion webUI

Google Colab 版的 Stable Diffusion WebUI 1.4 webui github 地址:https://github.com/sd-webui/stable-diffusion-webui 平台搭建 今天就来交大家如果来搭建和使用这个云平台。 第一步: 打开链接 https://colab.research.google.com/github/altryne/sd-webu…...

R.I.P,又一位程序员巨佬——左耳朵耗子陨落

震惊!谣言吧!求辟谣!默哀! 左耳朵耗子,在程序员这个群体里应该属于 GOAT 的存在了,虽然每个人心目中都有自己的 GOAT,但耗子叔的影响力可以说是有目共睹。 我也是在技术群刷到这张图片的&#…...

捷威信keithley吉时利2410数字源表 销售回收KEITHLEY2470新款源表

吉时利Keithley 2410 /2470高压源表/数字源表 产品概览 Keithley 2410 高压源表专为需要紧密耦合源和测量的测试应用而设计。Keithly 2410 提供精密电压和电流源以及测量功能。它既是高度稳定的直流电源,又是真正的仪器级 5-1/2 数字万用表。电源特性包括低噪声、…...

第二十九回:如何给ListView添加分隔线

文章目录 概念介绍添加方法使用属性装饰器 示例代码经验总结: 我们在上一章回中介绍了多种创建ListView的方式,本章回中将介绍" 如何给ListView添加分隔线".闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在这里说的分隔线也叫Divider,…...

用友 LRP计划维护视图

select planlotnumber 计划单号, demandId 自动编号, PartId 物料Id , sotype 单据类型(1:销售/2:预测), sodid 销售订单明细Id , socode 销售订单单号 , soseq 销售订单行号, PlanCode 计划单号 , DueDate 完工日期 , StartDate 开工日期 , UnitCode 主计量单位, C…...

数组--part 5--螺旋矩阵(力扣59/54)(剑指offer 29)

文章目录 基本算法思想leetcode 59 螺旋矩阵 IIleetcode 54 螺旋矩阵剑指Offer 29 顺时针打印矩阵 基本算法思想 建议先去把题目看了,再来思考相关的代码。 错误的想法:实际上这种题型并不存在算法,只涉及到模拟,但是模拟难度并…...

加密解密软件VMProtect入门使用教程(九)许可制度之许可系统功能

VMProtect是新一代软件保护实用程序。VMProtect支持德尔菲、Borland C Builder、Visual C/C、Visual Basic(本机)、Virtual Pascal和XCode编译器。 同时,VMProtect有一个内置的反汇编程序,可以与Windows和Mac OS X可执行文件一起…...

MySQL基础-事务详解

本文主要介绍MySQL事务 文章目录 前言事务定义事务四大特性(ACID) 事务操作事务并发问题事务隔离级别 前言 参考链接: 链接1链接2 事务定义 事务是一组操作的集合,他是一个不可分割的工作单位,事务会把所有的操作作…...

python 读写csv文件方法

csv是一种结构化文件,可以将文本转化成矩阵的形式,方便程序读取和处理。下面来介绍一下使用 python读写 csv文件的方法: 1.首先需要使用 pip安装 python包,然后将 csv文件解压到一个文件夹下 2.使用 pip安装 python包,…...

命令行更新Windows

命令行更新Windows powershell命令行更新安装 Windows Update module for Windows Powershell连接到 Windows Update 服务器并下载更新安装下载好的 Windows Update 更新 cmd执行Windows update更新检查更新下载 Windows Update 更新安装更新安装更新后重新启动设备 win10以下版…...

lwIP 多线程注意事项

关于 lwIP 多线程的总结: lwIP 内核不是线程安全的。如果在多线程环境中使用 lwIP,必须使用高层次的 Sequential 或 socket API。使用 raw API 时,需要自己保护好应用程序和协议栈核心代码。在无操作系统环境中使用 raw API: 使用…...

工业革命的本质是动力革命:人类使用能量的水平得到了飞跃(蒸汽动力取代畜力和水力,机械代替人工。)【工业革命的诞生是能量富余的结果】

文章目录 引言I 用能量守恒方式看工业革命的影响1.1 中学物理能量守恒1.2 看清历史事件的影响1.3 工业革命的意义1.4 透过现象看本质的方法II 工业革命的本质2.1 动力革命2.2 多余的能量造就了工业革命引言 人类文明进步的目的是改善人们的生活,任何文明都以养活更多的人口为…...

【Kubernetes】Windows安装kubectl

准备开始 kubectl版本和集群版本之间的差异必须在一个小版本号内。 例如:v1.27版本的客户端能与 v1.26、 v1.27 和 v1.28 版本的控制面通信。 用最新兼容版的 kubectl 有助于避免不可预见的问题。 下载 官方安装文档: https://kubernetes.io/zh/docs/tasks/tools…...

菜鸟健身-新手使用哑铃锻炼手臂的动作与注意事项

目录 一、前言 二、哑铃锻炼手臂的好处 三、哑铃锻炼手臂的注意事项 四、哑铃锻炼手臂的基本动作 1. 哑铃弯举 2. 哑铃推举 3. 哑铃飞鸟 五、哑铃锻炼手臂的进阶动作 1. 哑铃侧平举 2. 哑铃俯身划船 六、哑铃锻炼手臂的训练计划 七、总结 一、前言 哑铃是一种非常…...

二、LLC 谐振变换器

半桥 LLC 谐振变换器主电路结构 如图所示,半桥 LLC 谐振变换器主电路可以分为四个部分,即:逆变网络、谐振网络、变压器及整流滤波网络。两个 MOSFET(S1、S2)以及它们的体二极管(D1、D2)和寄生电…...

JWT 入门

1.介绍 JSON Web Token(JWT)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO…...

理解HttpSession

什么是session 在我刚刚从事后端开发的时候,有一个问题困扰了我很久。 就有个玩意叫session。 PostMapping("login")public Result login(RequestParam("id") String id,RequestParam("password") String password, HttpSession se…...

SolVES 模型生态系统服务功能社会价值评估(基于多源环境QGIS、PostgreSQL、ArcGIS、Maxent、R语言)

查看原文>>>SolVES 模型生态系统服务功能社会价值评估(基于多源环境QGIS、PostgreSQL、ArcGIS、Maxent、R语言) 目录 第一章、理论基础与研究热点 第二章、SolVES 4.0 模型运行环境配置 第三章、SolVES 4.0 模型运行 第四章、数据获取与入…...

雷鸟Air Plus体验:视觉大幅升级,影视/办公/游戏全能胜任

雷鸟BirdBath系列XR眼镜一直保持着较快的迭代频率,如今迎来该系列第三款产品:雷鸟Air Plus,新品在视觉体验上得到大幅升级,不仅FOV达到49,边缘成像质量更高,搭配索尼旗舰级Micro OLED屏实现最高120Hz刷新率…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

测试markdown--肇兴

day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

Python如何给视频添加音频和字幕

在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...