Marie.js CPU仿真器学习笔记仿真器简单教程
传送门: ① Marie ② 使用手册
0、内容声明
本文章内容源于Marie.js使用手册,代码摘自Marie.js的样例代码,若有错误,敬请斧正。
1、Marie.js简介
这是一个非常精简易用的CPU仿真器,笔者曾自己用MFC写过类似的东西,但是效果和这个差了十万八千里。该仿真器是一个16位机,有三个通用寄存器,和一个只有16个指令的指令集,内存配置只有4K,不过这足够初学者研究一段时间了,但是它非常简单易用,满足了各种常用的X86架构和ARM架构处理器的指令。
2、配置介绍
如上图,共7个寄存器,意义如下:
AC 寄存器:通用寄存器、累加器,保存中间过程、累加、暂存等功能。
PC 寄存器:程序计数器,指向内存中下一条要执行的指令
MAR 寄存器:内存访问寄存器,简简单单的与地址线相连
MBR 寄存器:内存缓冲寄存器,简简单单的与数据线相连
IR 寄存器:指令寄存器,存放当前在执行的指令
Out、In寄存器:通用寄存器,I/O会使用这两个寄存器,不是用I/O时,可以当做通用寄存器用
7个寄存器和内存共8中调取数据的方式,正好可以使用3位表示。其中,MAR和PC因为和内存地址交互,只有12位,其余5个寄存器和内存中的字均为16位。
3、指令集
数学逻辑运算
Add X | 将X作为操作数,与AC相加,并保存到AC中 | |
Subt X | 将X作为操作数,用AC减之,并保存到AC中 | |
Addl X | 将X作为操作数的指针,与AC相加,并保存到AC中 | |
Clear | 将AC清零 |
与内存的数据交换
Load X | 从内存地址X中取数存值AC | |
Store X | 将AC存入地址为X的内存中 | |
Loadl X | 将X处存储的内容作为指针,获取操作数存入AC | |
Storel X | 将X处存储的内容作为指针,将AC的值存入指向的内存 |
I/O
Input | 要求用户输入一个值替换当前AC | ---- |
Output | 将AC的值输出 | ---- |
分支
Jump X | PC跳转到X的地址 |
---- |
Skipcond(C) | 基于AC和C跳过下一条语句的执行 |
跳转条件: C=000&&AC<0 C=400&&AC=0 C=800&&AC>0 |
子程序
JnS X | 将PC存至X的地址并且跳转至X+1 |
Jump X+1 |
Jumpl X | PC跳转到X指向的地方 |
后续单有一部分说明子程序/子函数的执行过程
程序终止
Halt | 程序终止 | ---- |
共16个指令,可以用4位表示
4、寻址方式
按照指令集中的指令名称,可以发现有部分指令有两种形式,即不带‘l'的形式和带'l'的形式。如:
Add | Addl |
Load | Loadl |
Store | Storel |
Jump | Jumpl |
左侧的一列为不含‘l’的指令,右侧为含‘l’的指令,左侧直接将存储空间X中存储的内容作为操作数,为直接寻址;右侧将存储空间X中存储的内容作为指针,使用指针寻找操作数,为间接寻址。
类似的直接寻址指令还有subt等;类似的间接寻址指令还有JnS等。
5、简单代码示例与注释
加法代码
//输入X和Y,并存储至内存
Input
Store X
Input
Store Y//AC中当前存储的是Y,所以Add X即可完成加法过程
Add X
Output
Halt//声明内存空间
X, DEC 0
Y, DEC 0
HelloWorld
LOOP, Load PTR
// 输出字符
LoadI PTR
Output// 字符串指针自增
Load PTR
Add ONE
Store PTR// 计数器自增
Load CTR
Add ONE
Store CTR// 检查计数个数,是否完全输出字符串
Subt WORDS
Skipcond 400
Jump LOOP
Halt// 数据空间
ONE, DEC 1
CTR, DEC 0
WORDS, DEC 12// 初始化指针指向字符串
PTR, ADR S// "Hello World!"
S, HEX 48
HEX 45
HEX 4C
HEX 4C
HEX 4F
HEX 20
HEX 57
HEX 4F
HEX 52
HEX 4C
HEX 44
HEX 21
6、子程序/子函数代码过程
先上代码
//调用子函数
JnS func
Halt
func, HEX 000 // 此处保存要返回的地址...Jumpl func
这段代码中,func是一个函数的入口地址,JnS将PC指向func的下一字,跳过的一字保存这跳之前指针的下一位置,跳之前语句为JnS,那么下一个位置(本程序中为Halt),也就是函数返回之后要继续执行的位置。
那么代码是如何返回的呢?func函数执行完毕后,Jumpl将func作为指针间接寻址,将其地址赋值给PC,本程序中也就是Halt语句的地址被赋值给了PC,那么程序就可以正常返回了!
7、其它注意事项
Marie中对数据段和代码段没有加以区分,为了避免将数据当作代码执行,应当将数据放置于代码之后,但是有特殊情况,如子程序中,程序的返回地址会放在程序开头的位置,也正是因为这样的机制,可以让如此精简的Marie可以使用子函数的功能。
关于内存中“数据段”中数据的常见表示格式,见下表:
DEC | 十进制 |
HEX | 十六进制 |
ADR | 地址标签(一般做指针用) |
内存的4K容量为内存中字的数量,共4K个16位的字,实际内存为8KB。
推荐的代码格式:
先数据再代码
Jump begin//此为数据段...
//数据段结束begin,
//此为主程序...Halt
//主程序结束func1,Hex 000
//子程序1...Jumpl func1
//子程序1结束...
先代码再数据
//此为主程序
...
Halt
//主程序结束func1,Hex 000
//子程序1...Jumpl func1
//子程序1结束...//此为数据段...
//数据段结束
每个子函数前有所需数据
Jump begin//主程序数据段begin,
//此为主程序...Halt
//主程序结束//子程序1数据段func1,Hex 000
//子程序1...Jumpl func1
//子程序1结束...
关于注释的问题:单斜线'/'即可完成整行的注释,上述代码中写双斜线是为了满足CSDN的C++代码的格式要求,如果个人习惯双斜线,也可以使用
Marie.js CPU仿真器学习笔记仿真器简单教程相关推荐
- STM32F429I-Discovery学习笔记--(1)简单上手和官方例程的下载与使用
STM32F429I-Discovery学习笔记–(1)简单上手和官方例程的下载与使用 到手测试 收到开发板后我们要首先检查一下外观有没有磕碰破损,排针是否发生弯折,重要的是看一下JP3和CN4处的跳 ...
- python自训练神经网络_tensorflow学习笔记之简单的神经网络训练和测试
本文实例为大家分享了用简单的神经网络来训练和测试的具体代码,供大家参考,具体内容如下 刚开始学习tf时,我们从简单的地方开始.卷积神经网络(CNN)是由简单的神经网络(NN)发展而来的,因此,我们的第 ...
- VC学习笔记:简单绘图
VC学习笔记:简单绘图 SkySeraph Oct.29th 2009 HQU Email-zgzhaobo@gmail.com QQ-452728574 Latest Modified Date ...
- Tensorflow2学习笔记:简单灰度图分类
Tensorflow2学习笔记:简单灰度图分类 相关介绍 实验环境 实验步骤 导入相关库 导入数据集 浏览数据 预处理数据 构建模型 设置层 编译模型 训练模型 向模型馈送数据 评估准确率 进行预测 ...
- html5教程 w3cschool,W3Cschool学习笔记——HTML5基础教程
HTML5 建立的一些规则:新特性应该基于 HTML.CSS.DOM 以及 JavaScript. 减少对外部插件的需求(比如 Flash) 更优秀的错误处理 更多取代脚本的标记 HTML5 应该独立 ...
- x%3e=y%3e=z的c语言表达式,我的C语学习笔记-C语言教程(三).doc
我的C语学习笔记- C语言教程(三) C语言教程---第一章: C语言概论 C语言教程---第二章: 数据类型.运算符.表达式 C语言教程---第三章: C语言程序设计初步 C语言教程---第四章: ...
- c语言第七章函数笔记,我的C语学习笔记-C语言教程(七).doc
我的C语学习笔记- C语言教程(七) C语言教程---第一章: C语言概论 C语言教程---第二章: 数据类型.运算符.表达式 C语言教程---第三章: C语言程序设计初步 C语言教程---第四章: ...
- java学习笔记2(datawhale教程):运算符和表达式、流程控制、数组
java学习笔记2(datawhale教程):运算符和表达式.流程控制.数组 文章目录 java学习笔记2(datawhale教程):运算符和表达式.流程控制.数组 一.运算符和表达式 1.数学函数与 ...
- 【Unity学习笔记】UnrealToUnity教程:(网上购买的素材导入Unreal+插件转Unity)
[Unity学习笔记]UnrealToUnity教程: 最近想从Unreal那边化点缘借借素材,没想到踩到一个大坑 一,素材导入Unreal 这个教程比较多,根据素材的来源,传送门是以下这几个: 1. ...
最新文章
- DotNet关键知识点——WCF篇(六)
- linux 物理内存用完了_Linux用户空间与内核空间(理解高端内存)
- synchronized底层是怎么实现的?年薪超过80万!
- 2017寒假第一篇随笔(寒假作业一)
- java 根据类名示例化类_Java即时类| from()方法与示例
- Educational Codeforces Round 112 (Rated for Div. 2)(A-D)
- 智慧交通day00-项目简介
- JAVA WEB框架的错误体系
- 魅族营销翻车,被骂上热搜,官博致歉并暂停运营两天...
- tomcat xjar 加密_XJar Spring Boot JAR 安全加密运行工具
- python read函数报错_python 使用read_csv读取 CSV 文件时报错
- Python使用元类约束派生类中必须实现指定的成员
- disable jboss JMXInvokerServlet .
- 同步互斥阻塞 (2)
- maven项目的构建
- 服务器TPMC值计算
- git gitgitgitgitgit
- 英语四级考试计算机游戏,四级你过了吗电脑版
- 安卓10不支持qmc解码_Root神器支持安卓10 面具Magisk v20.4+Magisk Manager v7.5.1
- android定位方式