处理器指令编码可重定义的方法_从零开始设计四位栈处理器(2)——结构与指令集...

87f179aedc0ecceaeb8ba2d63ef4400b.png

从零设计四位栈处理器(2)——结构与指令集

一句话概括: 在Toxic处理器中,万物皆栈。

熟悉汇编语言的同学会了解,一般的汇编语言,会包含以下几个部分:

  1. 寄存器
  2. 地址
  3. 立即数
  4. 操作码

在这期文章中,我们将通过类比的方法来解释Toxic处理器的运行方法以及设计上作出的妥协。

088337a5ec25b5dfebbf271799d7dc72.png

上图显示的是RISC-V的最基础的四类指令,其中R类负责寄存器与寄存器之间的运算操作,I类负责寄存器和小立即数之间的操作,S类负责写入内存(读取指令被归结为I类内),U类负责处理大立即数以及PC相关的寻址。

一、寄存器

寄存器的本质是用来暂存数据,避免读写内存带来的巨大性能开销。

我们先举一个R类RISC-V汇编的例子:

add x1, x1, x1

这条命令的意思是:将x1寄存器的值与x1寄存器相加,并且将结果写入x1寄存器。

事实上这是一个非常典型的寄存器寻址的汇编指令,在X86构架、ARM构架和MIPS构架中几乎都能找到相似的指令。

但是我们在Toxic处理器中并没有这样的指令出现。那么我们为什么不用这种类型的指令呢?

我们上面展现的汇编代码来自RV32I指令集,本质上是一个32位整数指令集,在该指令集中总共定义了32个通用寄存器。我们为了寻址32个寄存器,在指令中每包含一个寄存器,需要花费log_2(32)=5比特的宽度。

而Toxic处理器是一个4位等长指令处理器,而4位二进制码只有16种不同的组合,这也就导致了在Toxic处理器中应用这种“寄存器寻址”的体系是非常不现实的:一条指令总共只有4比特,算上操作码占的空间,我们恐怕最多只能留2位给寄存器寻址,但这显然是不够的。所以既想维持4位的简洁又想拥有更多的”暂存空间“要怎么办呢?

于是我们引出了:Stack Machine(栈处理器)这个概念。

所谓栈处理器是相对于寄存器处理器而言的,一个栈处理器是不存在通用寄存器的,取而代之的是一个“栈”。栈这个概念相信各位已经非常清楚了,Toxic处理器里面的栈和我们通常说的栈道理上是完全相同的。不同之处在于:1. Toxic处理器的栈是由硬件逻辑门实现。2. Toxic处理器的栈,除了实现了push,pop之外,还实现了tos和ntos两个功能。tos就是所谓的栈顶,ntos就是次栈顶,在访问tos和ntos的时候不会改变栈内部的内容。

在这里,我们将这个作用是“替代通用寄存器”的栈命名为:数据栈。

二、地址

以RV32I为例,如果我们有一个32位宽度的总线,那么我们总共可以寻址的空间是2^32 Byte(假设每个地址寻1 Byte)。这个寻址空间说大不大,但是对于普通应用来说已经足够了。

但是Toxic处理器是一个四位处理器,2^4=16 Byte的寻址空间对于几乎任何程序来说都是不够的。很自然的我们就可以想到去运用多个4位总线连接起来一同来寻址,这样的话可以扩大我们的寻址空间。于是乎就出现了一个问题:到底要多大的寻址空间才好呢?在这里,Toxic处理器的设计给每个去尝试实现它的人都留下了空间,我们规定:总线宽度只要为4位的倍数,都可以让Toxic指令集良好的工作。

在开头我们就说过:Toxic处理器中,万物皆栈。与数据栈的思路相同,我们同样用栈来表示一个总线地址,在此我们称之为:地址栈。

8位的地址栈的实现与数据栈基本相同,为了避免混淆,我们暂时不引入更高位的地址栈的设计。

到此为止,我们已经讲述了Toxic处理器中最重要的两个部件。如果你感觉有似懂非懂的地方,没有关系,在我们一步步解释整个Toxic指令集之后你会有更清晰的认识。

三、立即数

立即数在处理器中的作用是将指令中的数直接作为处理器内的数据进行计算。

用RV32I指令集举个例子:

addi x1, x1, 1

该指令的意思是:将x1寄存器+1的结果存进x1寄存器。在该指令中,数字1就是一个立即数。

对于我们的Toxic处理器来说,处理立即数的本质就是将我们指定的任何一个数字,push进数据栈内。

下图是Toxic指令集的所有指令以及编码:

2ef0822c038b97387df3de79021ed419.png

在了解生成立即数的具体操作之前我们先看3个指令:P1, ADD, LS。

  • P1: 将数据“1”push进数据栈。
  • ADD:将数据栈tos和ntos的加和push进数据栈。
  • LS:将数据栈中的tos左移一位。

明白了这三个指令的操作,我们来思考一下:如何把“5”这个数字push到数据栈内呢?

首先,5的二进制是:0101。我们有以下代码:

P1 // tos为0001
LS // tos为0010
LS // tos为0100
P1 // tos为0001, 这时候之前的tos已经成为了ntos,为0100
ADD // 0001 + 0100 = 0101;这时候tos为0101,我们完成了将“5”push到栈顶

为了更高效的生成立即数比如说:15(也就是二进制中的1111),我们引入了P11这个指令,P11所做的事情与P1类似,就是将0011给push到栈顶。

四、操作码

操作码是指在机械码中存在的用来指定处理器指令的几位。

在RV32I指令集中,我们可以看到0-6位都是“opcode”,也就是我们说的操作码。

再次地,Toxic指令集是一个4位等长指令指令集。

然而不难发现,在Toxic指令集中,我们虽然只有4位的空间来描述一个指令,但是我们对于寄存器的寻址并不占用指令空间,对总线地址的访问也不占用指令空间,甚至连对寄存器的操作都不占用指令空间。所以,到最后,所有4位空间,我们都将分配给操作码。换句话说,在Toxic指令集中,所有机器码都是操作码。

(其实关于操作码的界定问题,学术界也没有一个非常准确的标准,比如说很多时候,RV32I的funct3都会被说成操作码的一部分。但是这都不重要,只是个人的区分和习惯问题)

我们这期文章就暂时先讲这么多,下期文章我们会更加仔细、更加完整的解读这16条指令,并且聊一聊如何用Toxic指令集编写一个真实有意义的程序。在讲完指令集后会讲一下整个Toxic处理器电路层面的实现。

当然,在那之前还有很多工作需要完善,大家可以先看看我的GitHub上Toxic_v2的英文文档还有最近很快就要完成了的Toxic_v2模拟器,如果大家能给我点个星星,我会非常感谢:

文档:https://github.com/Entropy-xcy/Toxic_v2

模拟器:https://github.com/Entropy-xcy/Toxic_v2_simulator

引用:

【1】 RISC-V ISA Specifications: https://riscv.org/specifications/

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

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

相关文章

raptor累乘流程图_Markdown快速上手指南

Markdown快速上手指南1、Markdown介绍markdown可以实现快速html文档编辑,格式优没,并且不需要使用html元素。 markdown采用普通文本的形式,例如读书笔记等易于使用的文本格式进行编写。 如果实在需要生成markdown不支持的html元素的话&#x…

LeetCode 1764. 通过连接另一个数组的子数组得到一个数组

文章目录1. 题目2. 解题1. 题目 给你一个长度为 n 的二维整数数组 groups ,同时给你一个整数数组 nums 。 你是否可以从 nums 中选出 n 个 不相交 的子数组,使得第 i 个子数组与 groups[i] (下标从 0 开始)完全相同,…

db文件怎么修改_MongoDB最新4.2.7版本三分片集群修改IP实操演练

背景重新组网,需要对现有MongoDB分片集群服务器的IP进行更改,因此也需要对MongoDB分片集群的IP也进行相应的更新,而MongoDB分片集群的IP修改不能单纯的通过配置来进行,需要一番折腾后才能正常更新,这里对整个MongoDB集…

cron 每周一执行_详解定时任务中的 cron 表达式

1.前言 我们经常使用 cron 表达式来定义定时任务的执行策略,今天我们就总结一下 cron 表达式的一些相关知识。 2. cron 表达式的定义 cron 表达式是一个字符串,该字符串由 6 个空格分为 7 个域,每一个域代表一个时间单位。格式如下: [秒] [分] [时] [日] [月] [周] [年] 通…

OGEngine教程:声音载入

以下介绍声音资源从载入到播放的一个流程 首先,我们将须要的音频文件放到assets文件夹下,OGE中SoundRes和MusicRes为我们封装了非常多经常使用的方法,能够用于载入及播放等经常使用功能。 载入 //设置声音读取路径 Device.getDevice().getSou…

LeetCode 1765. 地图中的最高点(BFS)

文章目录1. 题目2. 解题1. 题目 给你一个大小为 m x n 的整数矩阵 isWater ,它代表了一个由 陆地 和 水域 单元格组成的地图。 如果 isWater[i][j] 0 ,格子 (i, j) 是一个 陆地 格子。 如果 isWater[i][j] 1 ,格子 (i, j) 是一个 水域 格…

LeetCode 1768. 交替合并字符串

文章目录1. 题目2. 解题1. 题目 给你两个字符串 word1 和 word2 。 请你从 word1 开始,通过交替添加字母来合并字符串。 如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。 返回 合并后的字符串 。 示例 1: 输入…

.git文件夹_Git幸存者指南

> Learn how to use Git to version control a cake recipe… and other things like code!或如何用Git烤蛋糕Git很难。 Git令人生畏。 学习曲线很大。 作为软件工程师,这至关重要。Git是用于版本控制的行业标准。 这是我们大多数人在学校或编码训练营中都不学的…

mysql偏移注入_移位溢注:告别靠人品的偏移注入

*本文原创作者:SeagullGR,本文属FreeBuf原创奖励计划,未经许可禁止转载在Access数据库类型注入的时候,我们获取不到列名(前提是有表名),一般会选择使用偏移注入,但是这种注入方式往往借助的是个人的人品&am…

LeetCode 1769. 移动所有球到每个盒子所需的最小操作数(前缀和)

文章目录1. 题目2. 解题1. 题目 有 n 个盒子。给你一个长度为 n 的二进制字符串 boxes ,其中 boxes[i] 的值为 0 表示第 i 个盒子是 空 的,而 boxes[i] 的值为 1 表示盒子里有 一个 小球。 在一步操作中,你可以将 一个 小球从某个盒子移动到…

python3知识点汇总_35个高级Python知识点总结

No.1 一切皆对象 众所周知,Java中强调“一切皆对象”,但是Python中的面向对象比Java更加彻底,因为Python中的类(class)也是对象,函数(function)也是对象,而且Python的代码和模块也都是对象。 Py…

LeetCode 1770. 执行乘法运算的最大分数(DP)

文章目录1. 题目2. 解题1. 题目 给你两个长度分别 n 和 m 的整数数组 nums 和 multipliers ,其中 n > m ,数组下标 从 1 开始 计数。 初始时,你的分数为 0 。 你需要执行恰好 m 步操作。在第 i 步操作(从 1 开始 计数&#x…

统计--过滤(筛选)索引的统计信息过期问题测试

基础知识普及: 对于筛选索引,MSDN如是说: 筛选索引是一种经过优化的非聚集索引,尤其适用于涵盖从定义完善的数据子集中选择数据的查询。 筛选索引使用筛选谓词对表中的部分行进行索引。 与全表索引相比,设计良好的筛选…

IDEA连接mysql出现时区错误_idea连接数据库时区错误

错误界面IDEA连接mysql,地址,用户名,密码,数据库名,全都配置好了,点测试连接,咔!不成功!界面是这样的,翻译过来就是:服务器返回无效时区。进入“高…

LeetCode 1771. 由子序列构造的最长回文串的长度(最长回文子序)

文章目录1. 题目2. 解题1. 题目 给你两个字符串 word1 和 word2 ,请你按下述方法构造一个字符串: 从 word1 中选出某个 非空 子序列 subsequence1 。从 word2 中选出某个 非空 子序列 subsequence2 。连接两个子序列 subsequence1 subsequence2 &…

python牛顿法计算平方根_常用的平方根算法详解与实现

本文从属于笔者的数据结构与算法系列文章。 SquareRoot 平方根计算一直是计算系统的常用算法,本文列举出几张简单易懂的平方根算法讲解与实现。其中Java版本的代码参考这里 Reference Babylonian:巴比伦算法/牛顿法 巴比伦算法可能算是最早的用于计算$sqrt{S}$的算法…

什么是spring_Spring 源码第三弹!EntityResolver 是个什么鬼?

上篇文章和小伙伴们说了 Spring 源码中 XML 文件的解析流程,本来可以继续往下走看加载核心类了,但是松哥还是希望能够慢一点,既然要学就学懂,在 XML 文件解析的过程中还涉及到一些其他的类和概念,因此我就先用几篇文章…

从RAID看垂直伸缩到水平伸缩的演化

learn from 从0开始学大数据(极客时间) 大规模数据存储问题: 容量问题,数据量超过磁盘容量读写速度,磁盘读写慢数据可靠性,磁盘寿命问题 RAID(独立磁盘冗余阵列) 是将多块普通磁盘…

linux安装g++编译器_Ubuntu Desktop下配置Rosetta安装教程

作者: 吴炜坤本文仅在虚拟机环境下测试,可能实际操作中会遇到不同的问题本文是新手向的安装教程,如果需要在CentOS上安装,可以参考本人其他安装教程由于许多新人朋友在学习Rosetta过程中,通常操作系统选择的都是带美丽漂亮界面便于…

HDFS依然是存储的王者

learn from 从0开始学大数据(极客时间) 1. HDFS 架构 DataNode 负责数据的存储、读写,HDFS 将文件分割成若干数据块(Block),每个 DataNode 存储一部分数据块,文件就分布存储在整个 HDFS 服务器集…