博客
关于我
实践: 《编码:隐匿在计算机软硬件背后的语言》 -- 实现一个简单的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/

你可能感兴趣的文章
MySQLIntegrityConstraintViolationException异常处理
查看>>
mysqlreport分析工具详解
查看>>
MySQLSyntaxErrorException: Unknown error 1146和SQLSyntaxErrorException: Unknown error 1146
查看>>
Mysql_Postgresql中_geometry数据操作_st_astext_GeomFromEWKT函数_在java中转换geometry的16进制数据---PostgreSQL工作笔记007
查看>>
mysql_real_connect 参数注意
查看>>
mysql_secure_installation初始化数据库报Access denied
查看>>
MySQL_西安11月销售昨日未上架的产品_20161212
查看>>
Mysql——深入浅出InnoDB底层原理
查看>>
MySQL“被动”性能优化汇总
查看>>
MySQL、HBase 和 Elasticsearch:特点与区别详解
查看>>
MySQL、Redis高频面试题汇总
查看>>
MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
查看>>
mysql一个字段为空时使用另一个字段排序
查看>>
MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
查看>>
MYSQL一直显示正在启动
查看>>
MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
查看>>
MySQL万字总结!超详细!
查看>>
Mysql下载以及安装(新手入门,超详细)
查看>>
MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
查看>>
MySQL不同字符集及排序规则详解:业务场景下的最佳选
查看>>