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

C语言模拟最简单的计算机

C语言模拟最简单的计算机

以下内容参考南大“计算机系统基础”实验:不停计算的机器

概述

如下面的伪代码所示,计算机运行程序的过程为取指令–>运行指令–>更新PC的值。

while (1) {从PC指示的存储器位置取出指令;执行指令;更新PC;
}

取指(instruction fetch, IF)

执行一条指令前, 首先要拿到这条指令。指令究竟在哪里呢? 还记得冯诺依曼体系结构的核心思想吗? 那就是"存储程序, 程序控制".
这两句话告诉我们, 指令被放在存储器中, 由PC指出当前指令的位置. 事实上, PC就是一个指针!!!
取指令要做的事情自然就是将PC指向的指令从内存读入到CPU中。

译码(instruction decode, ID)

在取指阶段, 计算机拿到了将要执行的指令. 让我们来看看这个指令的·面貌, 睁大眼睛一看, 竟然是个0和1组成的比特串!

10111001 00110100 00010010 00000000 00000000

计算机也只是个巨大的数字电路, 它只能理解0和1。
拿到指令后,我们需要对指令进行翻译。指令通常包含操作码和操作数两个部分的信息。根据操作码的含义去执行对应的操作,操作数一般作为该操作需要的数据。

执行(execute, EX)

经过译码之后, CPU就知道当前指令具体要做什么了, 执行阶段就是真正完成指令的工作. 现在TRM只有加法器这一个执行部件, 必要的时候,
只需要往加法器输入两个源操作数, 就能得到执行的结果了. 之后还要把结果写回到目的操作数中, 可能是寄存器, 也可能是内存.

更新PC

更新PC

执行完一条指令之后, CPU就要执行下一条指令. 在这之前, CPU需要更新PC的值, 让PC加上刚才执行完的指令的长度,
即可指向下一条指令的位置.

代码实操

这里直接从南京大学“计算机系统基础”实验搬过来:不停计算的机器
为南大打call !!!

模拟的计算机有4个8位的寄存器, 一个4位PC, 以及一段16字节的内存. 它支持R型和M型两种指令格式, 4条指令. 其指令手册如下:

                                                     4  2  0|                        |        | +----+--+--+
mov   rt,rs | R[rt] <- R[rs]         | R-type | |0000|rt|rs||                        |        | +----+--+--+|                        |        | +----+--+--+
add   rt,rs | R[rt] <- R[rs] + R[rt] | R-type | |0001|rt|rs||                        |        | +----+--+--+|                        |        | +----+--+--+
load  addr  | R[0] <- M[addr]        | M-type | |1110| addr||                        |        | +----+--+--+|                        |        | +----+--+--+
store addr  | M[addr] <- R[0]        | M-type | |1111| addr||                        |        | +----+--+--+
#include <stdint.h>
#include <stdio.h>#define NREG 4
#define NMEM 16// 定义指令格式
typedef union {struct { uint8_t rs : 2, rt : 2, op : 4; } rtype;struct { uint8_t addr : 4      , op : 4; } mtype;uint8_t inst;
} inst_t;#define DECODE_R(inst) uint8_t rt = (inst).rtype.rt, rs = (inst).rtype.rs
#define DECODE_M(inst) uint8_t addr = (inst).mtype.addruint8_t pc = 0;       // PC, C语言中没有4位的数据类型, 我们采用8位类型来表示
uint8_t R[NREG] = {}; // 寄存器
uint8_t M[NMEM] = {   // 内存, 其中包含一个计算z = x + y的程序0b11100110,  // load  6#     | R[0] <- M[y]0b00000100,  // mov   r1, r0 | R[1] <- R[0]0b11100101,  // load  5#     | R[0] <- M[x]0b00010001,  // add   r0, r1 | R[0] <- R[0] + R[1]0b11110111,  // store 7#     | M[z] <- R[0]0b00010000,  // x = 160b00100001,  // y = 330b00000000,  // z = 0
};int halt = 0; // 结束标志// 执行一条指令
void exec_once() {inst_t this;this.inst = M[pc]; // 取指switch (this.rtype.op) {//  操作码译码       操作数译码           执行case 0b0000: { DECODE_R(this); R[rt]   = R[rs];   break; }case 0b0001: { DECODE_R(this); R[rt]  += R[rs];   break; }case 0b1110: { DECODE_M(this); R[0]    = M[addr]; break; }case 0b1111: { DECODE_M(this); M[addr] = R[0];    break; }default:printf("Invalid instruction with opcode = %x, halting...\n", this.rtype.op);halt = 1;break;}pc ++; // 更新PC
}int main() {while (1) {exec_once();if (halt) break;}printf("The result of 16 + 33 is %d\n", M[7]);return 0;
}

相关文章:

C语言模拟最简单的计算机

C语言模拟最简单的计算机 以下内容参考南大“计算机系统基础”实验&#xff1a;不停计算的机器 概述 如下面的伪代码所示&#xff0c;计算机运行程序的过程为取指令–>运行指令–>更新PC的值。 while (1) {从PC指示的存储器位置取出指令;执行指令;更新PC; }取指(inst…...

c++图论免费ppt,简单深度理解图论

本篇博文想分享一个ppt,是帮助大家简单深度理解c图论. 作者承诺&#xff1a;分享的东西没有病毒&#xff0c;是资料。 分享的东西一个是ppt,ppt里面是150页的&#xff0c;里面将带领大家简单深度理解c图论&#xff0c;还有一个就是里面例题的数据&#xff0c;大家可以按照数据…...

xml中in的使用

目录 一、简介 二、使用 1、参数为list 2、参数为Array 3、参数为Map XML中大于、小于、不等于符号使用 一、简介 在xml中使用in查询需要使用foreach标签 <foreach item"item" collection"list" index"index" open"(" sep…...

Unity生命周期函数

1、Awake 当对象&#xff08;自己这个类对象&#xff0c;就是这个脚本&#xff09;被创建时 才会调用该生命周期函数 类似构造函数的存在 我们可以在一个类对象创建时进行一些初始化操作 2、OnEnable 失活激活&#xff08;这个勾&#xff09; 想要当一个对象&#xff08;游戏…...

【OpenCV入门】第六部分——腐蚀与膨胀

文章结构 腐蚀膨胀开运算闭运算形态学方法梯度运算顶帽运算黑帽运算 腐蚀 腐蚀操作可以让图像沿着自己的边界向内收缩。OpenCV通过”核“来实现收缩计算。“核”在形态学中可以理解为”由n个像素组成的像素块“&#xff0c;像素块包含一个核心&#xff08;通常在中央位置&…...

[C++] STL_list常用接口的模拟实现

文章目录 1、list的介绍与使用1.1 list的介绍1.2 list的使用 2、list迭代器3、list的构造4、list常用接口的实现4.1 list capacity4.2 插入删除、交换、清理4.2.1 insert任意位置插入4.2.2 push_front头插4.2.3 push_back尾插4.2.4 erase任意位置删除4.2.5 pop_front头删4.2.6 …...

js实现点击查看全部/收起功能

在上一篇文章实现用js截取文本后&#xff0c;我的另一个需求也迎刃而解了。需求就是一段长文本需要溢出隐藏&#xff0c;然后点击全部时显示全部文本&#xff0c;点击收起又回到溢出隐藏的状态。实现的效果如下图&#xff1a; 实现的思路时点击全部时使用这条数据的原文本&…...

安全区域边界技术测评要求项

1.边界防护-非授权设备接入、非授权连接外部网络、无线网络使用和设备可信接入 &#xff08;网络边界就是采用不同安全策略的两个网络的连接处&#xff09; 1-1/2-1/3-4/4-6 a&#xff09;保证跨越边界的访问和数据流通过边界设备提供的受控接口进行通信 b&#xff09;应能够对…...

基于YOLOV8模型的农作机器和行人目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOV8模型的农作机器和行人目标检测系统可用于日常生活中检测与定位农作机和行人目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标…...

我的私人笔记(安装hbase)

在安装前需要安装好JDK、Hadoop以及Zookeeper&#xff0c;JDK版本为1.8、Hadoop版本为2.7.4以及Zookeeper的版本为3.4.10。 4.1.下载 下载地址&#xff1a;Index of /dist/hbase 本次学习版本为&#xff1a; hbase-1.2.1-bin.tar.gz 4.2.安装步骤 上传安装包至hadoop01节点…...

【MySQL】用户管理

之前我们一直都使用root身份来对mysql进行操作&#xff0c;但这样存在安全隐患。这时&#xff0c;就需要使用MySQL的用户管理 目录 一、用户 1.1 用户信息 1.2 添加用户 1.3 删除用户 1.4 修改用户密码 二、用户权限 2.1 赋予授权 2.2 回收权限 一、用户 1.1 用户信息…...

音视频 ffmpeg命令转封装

保持编码格式&#xff1a; ffmpeg -i test.mp4 -vcodec copy -acodec copy test_copy.ts ffmpeg -i test.mp4 -codec copy test_copy2.ts改变编码格式&#xff1a; ffmpeg -i test.mp4 -vcodec libx265 -acodec libmp3lame out_h265_mp3.mkv修改帧率&#xff1a; ffmpeg -i …...

恢复已删除的git分支

1.打开对应项目文件夹目录,在目录下执行git命令 2.执行命令 git reflog --dateiso , 找到最后一次commit 的id 3. 执行git checkout -b 新建分支名称 commitId 就会基于commitId这次提交时工作区新建一个分支&#xff0c;就能达到我们找到删除分支的代码效果。 4.直接看ide…...

ATF(TF-A)安全通告 TFV-3 (CVE-2017-7563)

安全之安全(security)博客目录导读 ATF(TF-A)安全通告汇总 目录 一、ATF(TF-A)安全通告 TFV-3 (CVE-2017-7563) 二、CVE-2017-7563 一、ATF(TF-A)安全通告 TFV-3 (CVE-2017-7563) Title RO内存始终在AArch64 Secure EL1下可执行CVE ID CVE-2017-7563 Date 06 Apr 2017 Vers…...

虚拟机Ubuntu18.04系统使用时所需要的便利配置选项

文章目录 一、屏幕分辨率调节二、解决虚拟机和宿主机之间无法进行复制粘贴和自由移动文件&#xff1a;三、允许使用Git指令四、可以使用Cmake进行编译五、vi编辑器查看代码文件&#xff0c;类型linux的记事本 每次配置虚拟机&#xff0c;都需要重新安装配置一些能提供便利功能的…...

python内置函数

Python 解释器内置了很多函数和类型&#xff0c;任何时候都能使用。以下按字母顺序给出列表。 内置函数 A abs() aiter() all() any() anext() ascii() B bin() bool() breakpoint() bytearray() bytes() C callable() chr() classmethod() compile() complex() D delattr(…...

线性思维和系统思维

1 线性思维介绍 线性思维是一种直线的、均匀的、不变的、单一的、单维的思维方式&#xff0c;一切都随着初始条件的给定而给定。 线性思维的5种具体表现&#xff1a; 简单复制过往经验去推断未来 &#xff08;比如&#xff1a;银行工作者是铁饭碗&#xff09;用已知结果得出…...

为什么要学习C++

操作系统历史 UINX操作系统诞生之初是用汇编语言编写的。随着UNIX的发展&#xff0c;汇编语言的开发效率成为一个瓶颈。寻找新的高效开发语言成为UNIX开发者需要解决的问题。当时BCPL语言成为了当时的选择之一。Ken Thomposn对BCPL进行简化得到了B语言。但是B语言不是直接生成…...

eureka服务注册和服务发现

文章目录 问题实现以orderservice为例orderservice服务注册orderservice服务拉取 总结 问题 我们要在orderservice中根据查询到的userId来查询user&#xff0c;将user信息封装到查询到的order中。 一个微服务&#xff0c;既可以是服务提供者&#xff0c;又可以是服务消费者&a…...

QT的介绍和优点,以及使用QT初步完成一个登录界面

QT介绍 QT主要用于图形化界面的开发&#xff0c;QT是基于C编写的一套界面相关的类库&#xff0c;进程线程库&#xff0c;网络编程的库&#xff0c;数据库操作的库&#xff0c;文件操作的库…QT是一个跨平台的GUI图形化界面开发工具 QT的优点 跨平台&#xff0c;具有较为完备…...

MySQL教程

MySQL教程 数据库简介数据库的基本概念MySQL简介windows下安装MySQLLinux下安装MySQL在MacOS下面安装MySQLMySQL配置文件分析MySQL数据库的基本操作MySQL创建表MySQL插入数据MySQL删除数据MySQL修改数据MySQL基本查询MySQL可视化客户端SQL语句的分类MySQL的DDLMySQL的数据类型…...

深入理解协同过滤算法及其实现

导语 个性化推荐系统在现代数字时代扮演着重要的角色&#xff0c;协助用户发现他们可能感兴趣的信息、产品或媒体内容。协同过滤是个性化推荐系统中最流行和有效的算法之一。 目录 协同过滤算法的原理 基于用户的协同过滤&#xff08;User-Based Collaborative Filtering&am…...

力扣:随即指针138. 复制带随机指针的链表

复制带随机指针的链表 OJ链接 分析&#xff1a; 该题的大致题意就是有一个带随机指针的链表&#xff0c;复制这个链表但是不能指向原链表的节点&#xff0c;所以每一个节点都要复制一遍 大神思路&#xff1a; ps:我是学来的 上代码&#xff1a; struct Node* copyRandomList(s…...

【从0学习Solidity】合约入门 Hello Web3

【学习Solidity的基础】入门智能合约开发 Hello Web3 &#x1f4f1;不写代码没饭吃上架主页 在强者的眼中&#xff0c;没有最好&#xff0c;只有更好。我们是全栈开发领域的优质创作者&#xff0c;同时也是阿里云专家博主。 ✨ 关注我们的主页&#xff0c;探索全栈开发的无限…...

awtk-ftpd 发布

1. 介绍 在嵌入式应用程序中&#xff0c;有时需要提供一个 FTP 服务&#xff0c;用于对系统的文件进行远程管理。 awtk-ftpd 实现了一个 简单的 FTP 服务。主要特色有&#xff1a; 小巧。约 800 行代码。可以在各种嵌入式平台运行。内存开销低。正常内存需求小于 6K。兼容 F…...

抽象轻松的C语言

#include <stdio.h> /* 预处理指令*/ /* 函数 */ int main() {int log 3.14;printf("hello word * %d\n easy", log);getchar();/* 获取键盘输入的字母&#xff0c;在这个程序中的作用是防止程序瞬间关闭 */return 0; } 上一篇说过&#xff0c;C程序是C语言的…...

【力扣每日一题01】两数之和

开了一个新专栏&#xff0c;用来记录自己每天刷题&#xff0c;并且也是为了养成每日学习这个习惯&#xff0c;期待坚持一年后的自己&#xff01; 一、题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&am…...

机器学习——手写数字识别

0、&#xff1a;前言 这篇文章能够帮助你从数据到模型的整个过程实现不过至于安装第三方库等基础问题&#xff0c;本文不涉及&#xff0c;因为确实不难&#xff0c;搜一搜一大把本此实验运行环境为jupyter&#xff0c;当然通过pycharm也是可行的 1、数据&#xff1a; 手写数字…...

【日积月累】后端刷题日志

刷题日志 说说对Java的理解JAVA中抽象类和接口之间的区别Java中的泛型 和equals()的区别八种基本数据类型与他们的包装类在一个静态方法内调用一个非静态成员为什么是非法的静态方法与实例方法有何不同重载与重写深拷贝浅拷贝面向过程与面向对象成员变量与局部变量Spring框架Sp…...

Matlab在编码中增加CRC和交织功能

定义CRC生成和检验的类&#xff08;包括函数&#xff09; 我们在MATLAB中定义一个类&#xff08;class&#xff09;&#xff0c;包含了CRC生成函数和检验函数&#xff08;囊括了常用的CRC多项式&#xff09; classdef CRCpropertiesCRCbit_LenpolynomialCRCgenCRCdetendmetho…...