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

news2024/11/27 13:45:39

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

文章目录

  • 完善加法器
  • 加入代码的加法器
  • 扩大加数范围
  • 自由调用地址的加法器
  • 合并代码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指令。

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/529014.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在线域名批量查询工具-未注册域名批量查询软件

在线域名批量查询工具 在线域名批量查询工具是一种通过互联网进行批量查询域名相关信息和指标的工具。以下是其主要特点: 在线查询:在线域名批量查询工具可以直接在浏览器中进行查询,无需下载和安装任何软件。 批量查询:该工具…

内网渗透--frp代理设置与proxychains代理设置

标题内网渗透–frp代理设置与proxychains代理设置 内网服务器内网IP地址外网IP地址内网web服务器(windows 7)192.168.52.143192.168.213.138内网域控服务器192.168.52.138 外网服务器外网IP地址外网V8网卡外网kali192.168.213.132外网windows攻击机192…

开通小程序账号

文章目录 一、开通小程序账号1.1 登录微信公众平台注册小程序管理员账号1.2 激活邮箱1.3 信息登记 二、获取开发设置2.1 获取APP ID2.2 获取AppSecret 一、开通小程序账号 微信小程序已经成为移动应用开发的热门平台之一,许多开发者都想要开发自己的小程序。但是首先我们需要注…

Pandas中的逻辑运算符(与或非)及Python代码示例

Pandas是Python中一个非常流行的用于数据处理和分析的库,它提供了大量的函数和操作符,以便用户可以方便地对数据进行操纵。其中逻辑运算符是在Pandas中经常使用的一些操作符之一,因为它们使我们可以对数据进行逻辑上的比较和筛选。本篇博客将…

【Dart】=> [01] Dart基础-下载安装环境配置

目录 windows下载安装地址1. 下载dart-sdk并且解压到某盘符目录下2. 找到bin目录,复制bin目录完整路径3. 打开我的电脑,右键菜单,点击属性4. 找到高级系统设置,点击5. 点击环境变量![在这里插入图片描述](https://img-blog.csdnim…

串口监控的几种方式

目录 方法1. 使用usb转TTL模块硬件监控; 方法2. 使用JLINK的SWD接口的串口收发脚进行硬件监控; 方法3. 使用虚拟串口进行软件监控; 方法1. 使用usb转TTL模块硬件监控; 方法2. 使用JLINK的SWD接口的串口收发脚进行硬件监控&…

第十二章 使用Bind提供域名解析服务

文章目录 第十二章 使用Bind提供域名解析服务一、DNS域名解析服务1、DNS简介2、服务器类型3、13台根DNS服务器的具体信息 二、安装Bind服务程序1、Bind简介2、Bind安装3、关键配置文件4、修改主配置文件5、正向解析实验(1)、编辑区域配置文件&#xff08…

必须了解的内存屏障

目录 一,内存屏障1,概念2,内存屏障的效果3,cpu中的内存屏障 二,JVM中提供的四类内存屏障指令三,volatile 特性1,保证内存可见性定义2,禁止指令重排序3,不保证原子性 一&a…

Http与Https 比较

目录 1、HTTP(HyperText Transfer Protocol:超文本传输协议) 2、HTTPS(Hypertext Transfer Protocol Secure:超文本传输安全协议) 3、HTTP 与 HTTPS 区别 4、HTTPS 的工作原理 1、HTTP(HyperTex…

MySQL---存储过程(局部变量、用户变量、系统变量(全局变量、会话变量)、传参(in、out、inout))

1. 存储过程特性 存储过程就是数据库 SQL 语言层面的代码封装与重用。 有输入输出参数,可以声明变量,有if/else, case,while等控制语句,通过编写存储过程,可以实现 复杂的逻辑功能; 函数的普遍特性:模块…

全球特种无人机市场规模逐渐扩大,预计今年将突破120亿美元

翱翔于空中是人们长久的追求,1903年,莱特兄弟发明了第一家螺旋桨飞机,这次飞行标志着飞机时代的开始。科技发展到今天,无人机(英文简称为“UAV”)作为一种高科技产品已经逐渐走进人们的生活中。 无人机技术…

如何解决浏览器跨域问题?

浏览器判断是跨域请求会在请求头上添加origin,表示这个请求来源哪里。比如: Plaintext GET / HTTP/1.1 Origin: http://localhost:8601服务器收到请求判断这个Origin是否允许跨域,如果允许则在响应头中说明允许该来源的跨域请求,…

【windows批处理batch】批处理batch字符串处理相关操作(字符串定义、分割、拼接、替换、切片、查找)

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、…

从万和电气看民企如何获得“新增长”

改革开放至今,中国民营企业在经过蒙眼狂奔的三十多年后,普遍迎来发展难题: 1,第一代创业者普遍进入退休年龄,面临代际传承问题; 2,民营企业尤其是偏传统行业的企业,如何在新的行业…

基于SSM的高校图书借阅管理系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

mybatis-plus基本使用流程以及进阶操作

参考 https://www.bilibili.com/video/BV1dQ4y1A75e?p7&vd_source6346698154746eb5026e16499e253fe8 使用流程 一、 准备工作 3.引入依赖 4.插件 spring-boot-starter spring-boot-starter-test mybatis-plus-boot-starter MySQL lombok:用于简化实体类的创建…

查看 PostgreSQL 中的表定义和说明

要查看 PostgreSQL 中的表定义和说明&#xff0c;您可以使用以下命令&#xff1a; 1. 查看表定义&#xff1a; \d <table_name>例如&#xff0c;要查看 pg_extension 表的定义&#xff0c;您可以运行以下命令&#xff1a; \d pg_extension2. 查看表说明&#xff1a; …

山东移动:全业务域核心系统升级,实现大幅降本增效

本文介绍了山东移动引入 OceanBase 到山东省 BOSS/CRM 核心系统领域的相关情况。欢迎访问 OceanBase 官网获取更多信息&#xff1a;https://www.oceanbase.com/ 中国移动通信集团山东有限公司&#xff08;以下简称"山东移动"&#xff09; 隶属于中国移动通信集团公司…

【刷题之路】LeetCode 232. 用栈实现队列

【刷题之路】LeetCode 232. 用栈实现队列 一、题目描述二、解题1、图解主要思路2、先实现栈3、实现各个接口3.1、初始化接口3.2、入队接口3.3、出队接口3.4、取队头接口3.5、判空接口3.6、释放接口 一、题目描述 原题连接&#xff1a; 232. 用栈实现队列 题目描述&#xff1a;…

Babylon.js大规模场景优化实践

在本文中&#xff0c;我们将重点介绍用于优化 Babylon.js 海港场景的优化和架构技术。 我们的场景总共有超过 600 个网格和 1,000,000 个顶点。 在我们的 2018 Macbook Pro 上&#xff0c;它在 Google Chrome 中始终以 45 FPS 的速度运行。 我们发现 Firefox 约为 40 FPS&#…