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

执行完一条指令之后, 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;
}

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

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

相关文章

Flink中RPC实现原理简介

前提知识 Akka是一套可扩展、弹性和快速的系统&#xff0c;为此Flink基于Akka实现了一套内部的RPC通信框架&#xff1b;为此先对Akka进行了解 Akka Akka是使用Scala语言编写的库&#xff0c;基于Actor模型提供一个用于构建可扩展、弹性、快速响应的系统&#xff1b;并被应用…

3 | Java Spark 配置和 数据筛选

下面将演示如何使用 Apache Spark 的 Java API 来加载数据、筛选出偶数,并计算它们的总和。Apache Spark 是一个强大的分布式计算框架,适用于大规模数据处理任务。 创建 Maven 项目 首先,我们需要创建一个 Maven 项目,以便管理依赖项。在项目的 pom.xml 文件中添加以下 S…

feign调用失败 feign.RetryableException: xxx-service executing GET http://xxx/test

一。 问题引入 升级springcloud的版本后 突然发现 以前正常的feign调用也报错了 升级后的各组件版本如下 spring cloud 2021.0.5 spring cloud alibaba 2021.0.5.0 spring boot 2.6.13 错误日志如下 feign.RetryableException: xxx-service executing GET http://xxx-servic…

Servlet属性、监听者和会话

没有servlet能单独存在。在当前的现代Web应用中&#xff0c;许多组件都是在一起协作共同完成一个目标。怎么让这些组件共享信息&#xff1f;如何隐藏信息&#xff1f;怎样让信息做到线程安全&#xff1f; 1 属性和监听者 1.1 初始化 容器初始化一个servlet时&#xff0c;会为…

LeetCode--HOT100题(47)

目录 题目描述&#xff1a;105. 从前序与中序遍历序列构造二叉树&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;105. 从前序与中序遍历序列构造二叉树&#xff08;中等&#xff09; 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preo…

基于Vgg-Unet模型自动驾驶场景检测

1.VGG VGG全称是Visual Geometry Group属于牛津大学科学工程系&#xff0c;其发布了一些列以VGG开头的卷积网络模型&#xff0c;可以应用在人脸识别、图像分类等方面,VGG的输入被设置为大小为224x244的RGB图像。为训练集图像上的所有图像计算平均RGB值&#xff0c;然后将该图像…

系统错误码指示确立+日志模块手动配置

1&#xff0c;系统错误码指示确立 对于前后端分离的系统设计中&#xff0c;后端建立错误码指示对于前端非常重要可以指示错误存在地方&#xff1b;以用户注册为例&#xff1b; public interface SystemCode{int SYSTEM_USER_ERROR_ADD_FAIL 10000;int SYSTEM_USER_INFO_ADD …

Miniconda3环境迁移

问题&#xff1a; conda之前安装的默认路径空间满了没法进行安装&#xff0c;为此将其进行迁移&#xff0c;但是迁移之后报错 bash: /data/anaconda3/bin/conda: /home/anaconda3/bin/python: 坏的解释器: 没有那个文件或目录解决方案&#xff1a; 1、修改~/.bashrc中的环境…

B093-springsecurity整合jwt和RSA

目录 前后端分离后springsecurity核心filter的应用场景介绍JWT令牌的组成部分JWT案例导包TestJwt RSARsaUtilsTestRSA分析图 JWTRSA导包JwtUtilsTestRSAJWT 完善spring-security整合后且不连数据库的代码案例流程分析图 前后端分离后springsecurity核心filter的应用场景介绍 账…

15 验证差分时钟输入转单端

供给FPGA的时钟有单端时钟&#xff0c;也有差分时钟&#xff0c;当输入是差分时钟时&#xff0c;需要将差分时钟转换为单端时钟输出来作为FPGA的系统工作时钟。 本次使用锁相环来实现差分到单端时钟的转换。 FPGA代码实现如下&#xff1a; TOP层 timescale 1ns / 1ps // // …

Java设计模式:四、行为型模式-09:模板模式

文章目录 一、定义&#xff1a;模板模式二、模拟场景&#xff1a;模板模式三、改善代码&#xff1a;模板模式3.0 引入依赖3.1 工程结构3.2 模板模式结构图3.3 爬取商品生成海报实现3.3.1 HTTP获取连接类3.3.2 定义执行顺序的抽象类3.3.3 当当爬取抽象实现类3.3.4 京东爬取抽象实…

分享2款微课录制软件,保证让你满意!

“录微课用什么软件呀&#xff0c;真的服了&#xff0c;平台自带的录屏画质太差了&#xff0c;完全看不清讲的内容&#xff0c;而且音质也不是很好&#xff0c;大家有没有微课录制的软件推荐&#xff0c;谢谢啦” 随着教育方式的转型和技术的发展&#xff0c;微课程成为了一种…

【面试经典150题】跳跃游戏

题目链接 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 1 < nums…

422规范详解

概述&#xff1a; 全称为EIA-TIA-422-B&#xff0c;于1994年发布。 典型电路由一个发送器和N个接收器以及一个中断匹配电阻组成。 发送器&#xff1a; 差分输出电压值在2V~10V之间。 4.1.1 发送器输出阻抗 要求A/B之间的差分阻抗≤100Ω。 4.1.2 开路特性 要求差分电压≤…

Ansible 常用命令50条

以下是 Ansible 常用的 50 条命令&#xff1a; ansible --version: 查看 Ansible 版本信息。ansible all -m ping: 检查所有主机的连通性。ansible-playbook playbook.yml: 运行指定的 Ansible Playbook 文件。ansible-doc module_name: 查看指定模块的帮助文档。ansible-conf…

Hadoop服务脚本

#!/bin/bash process("NameNode" "SecondaryNameNode" "DataNode" "NodeManager" "ResourceManager") JAVA_HOME"/opt/software/jdk1.8.0_371" HADOOP_HOME"/opt/software/hadoop-3.3.6"# 定义颜色的AN…

从过滤器初识责任链设计模式

下面用的过滤器都是注解方式 可以使用非注解方式,就是去web.xml配置映射关系 上面程序的执行输出是 再加一个过滤器 下面来看一段程序 输出结果 和过滤器是否非常相识 但是上面这段程序存在的问题:在编译阶段已经完全确定了调用关系,如果你想改变他们的调用顺序或者继续添加一…

时序预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神…

淘宝API接口:提高电商运营效率与用户体验的利器(淘宝API接口使用指南)

淘宝API接口&#xff1a;提高电商运营效率与用户体验的利器 随着电商行业的快速发展&#xff0c;淘宝作为国内最大的电商平台之一&#xff0c;不断探索和创新&#xff0c;以满足不断变化的用户需求和商家需求。其中&#xff0c;淘宝API接口便是其创新的一个重要方面。本文将深…

【代码实现】DETR原文解读及代码实现细节

1 模型总览 宏观上来说&#xff0c;DETR主要包含三部分&#xff1a;以卷积神经网络为主的骨干网&#xff08;CNN Backbone&#xff09;、以TRM(Transformer)为主的特征抽取及交互器以及以FFN为主的分类和回归头&#xff0c;如DETR中build()函数所示。DETR最出彩的地方在于&…