博客
关于我
实践: 《编码:隐匿在计算机软硬件背后的语言》 -- 实现一个简单的8位CPU的虚拟机
阅读量:371 次
发布时间:2019-03-04

本文共 2274 字,大约阅读时间需要 7 分钟。

最近在看Charles Petzold的《编码》这本书。书上用生动的例子从导线灯泡继电器开关自己搭建了一个简单的8位计算机。

并且能实现加法,减法,条件判断,调整的基本功能。

这里博主为了巩固对书上知识的理解,用C++模拟书上的方法自己实现了一个8位的CPU虚拟机,并且支持内存的输入输出,和机器码。能自己编码运行程序。

Project Site:

https://github.com/sesiria/CodeMachine

1. 结构设计

采用C++ 来实现这个简单的8位计算机。

首先程序由主菜单(UI)

基本输入(获取各种命令)

执行命令(执行菜单项对应的命令)

整个程序是一个主循环,并且在进入和 退出主循环会进行虚拟机的初始化和反初始化(释放内存)等操作。

当然在执行命令过程中也运行进行中途初始化(Reset命令)

// Main function.int main(int argc, char * argv[], char* env[]) {	char sCommand[BUFSIZ];	initMachine();	printWelcome();	// main loop for standard IO	while (true){		getCommand(sCommand, _countof(sCommand));		if (processCommand(sCommand) == false)			break;	}	uninitMachine();	return 0;}

2. 基本输入输出

基本输入包括输入主菜单的各种命令。

Welcome to the Code Virtual Machine       v0.1 - Author: SesiriaPlease Input command:1. Input instructions(machine code). (I)2. Input assembly code. (A)3. Run code. (S)4. Reset machine. (R)5. Dump memory. (D)6. View Register. (V)7. Help. (H)8. Exit. (E)>
一个获取命令的函数getCommand( 用于获取用户的输入命令)和处理命令的函数processCommand(用于处理用户的选择的命令)。处理命令的过程会忽略无效的用户输入。如果用户选择了退出则直接退出主循环,并指向后续的关闭虚拟机的操作。

以下将说明各菜单项的命令和简单实现:

2.1. 输入代码 

基本输入中最重要的功能就是输入代码(机器指令)以16进制的方式向内测地址输入数据(可以是指令也可以是数据)通过函数

processInputInstruction()来实现。 

该函数判断用户的输入格式,如果是数据则在当前所指向的地址存入用户的输入数据(如果是无效数据会提示无效输入并继续的等待用户输入)并使地址指针指向下一个字节的内存单元(加1)。

用户的输入也可以是[地址]  数据 的方式。 改命令会修改当前指向的内存地址指针,随后输入的数据将以当前内存地址指针为基准,逐步递增。

该函数还对每次地址指针的自增做一个判断若指向内存的最后一个单元则自动指回 0x0000 (第一个单元)。

2.2 输入汇编

由于汇编代码的输入需要设计到字符串处理和宏处理,这里放到后续补完。

2.3 执行代码

将虚拟机指令指针所指向的第一条指令开始逐步执行,直到遇到HLT指令停止。

2.4 复位机器

2.5 显示内存内容

3. 机器内部结构模拟

首先设计一个结构体来存储机的RAM和各种寄存器。

typedef struct _kernalObj{	unsigned char * m_BUF;			// the main memory for the machine	unsigned char  m_A;				// the main register for the machine.	unsigned char  m_CI;			// the 'Carry character' In register for the accumulator.	unsigned char  m_CO;			// the 'Carry character' Out register for the accumulator.	unsigned char  m_ZF;			// the output zero flag for the accumulator.	unsigned char  m_CODE;			// the register for the Instructions	unsigned char  m_CL;			// the low 8bit address register for the Code.	unsigned char  m_CH;			// the high 8bit address register for the Code.	unsigned char  m_IP;			// the Instruction Pointer point to the memory address.}kernalObj;

initMachine()对虚拟机的个成员进行初始化操作,

uninitMachine() 会释放其中的m_BUF成员。

机器支持的指令表

4. 实现代码

转载地址:http://hobg.baihongyu.com/

你可能感兴趣的文章
NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
查看>>
NIFI同步MySql数据源数据_到原始库hbase_同时对数据进行实时分析处理_同步到清洗库_实际操作06---大数据之Nifi工作笔记0046
查看>>
Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
查看>>
NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
查看>>
NIFI大数据进阶_FlowFile生成器_GenerateFlowFile处理器_ReplaceText处理器_处理器介绍_处理过程说明---大数据之Nifi工作笔记0019
查看>>
NIFI大数据进阶_FlowFile生成器_GenerateFlowFile处理器_ReplaceText处理器_实际操作---大数据之Nifi工作笔记0020
查看>>
NIFI大数据进阶_Json内容转换为Hive支持的文本格式_实际操作_02---大数据之Nifi工作笔记0032
查看>>
NIFI大数据进阶_Json内容转换为Hive支持的文本格式_操作方法说明_01_EvaluteJsonPath处理器---大数据之Nifi工作笔记0031
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka消费者处理器_来消费kafka数据---大数据之Nifi工作笔记0037
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka生产者---大数据之Nifi工作笔记0036
查看>>
NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
查看>>
NIFI大数据进阶_NIFI监控功能实际操作_Summary查看系统和处理器运行情况_viewDataProvenance查看_---大数据之Nifi工作笔记0026
查看>>
NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
查看>>
NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
查看>>
NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
查看>>
NIFI大数据进阶_使用NIFI表达式语言_来获取自定义属性中的数据_NIFI表达式使用体验---大数据之Nifi工作笔记0024
查看>>
NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
查看>>
NIFI大数据进阶_内嵌ZK模式集群2_实际操作搭建NIFI内嵌模式集群---大数据之Nifi工作笔记0016
查看>>
NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
查看>>
NIFI大数据进阶_实时同步MySql的数据到Hive中去_可增量同步_实时监控MySql数据库变化_实际操作_03---大数据之Nifi工作笔记0035
查看>>