首页 > 编程 > Python > 正文

使用Python编写一个模仿CPU工作的程序

2020-02-23 00:45:42
字体:
来源:转载
供稿:网友

今天早上早些时候,在我的Planet Python源中,我读到了一篇有趣的文章"开发CARDIAC:纸板计算机(Developing upwards: CARDIAC: The Cardboard Computer)",它是关于名为Cardiac的纸板计算机的.我的一些追随者和读者应该知道,我有一个名为简单CPU(simple-cpu)的项目,过去的数月我一直工作于此,并且已经发布了源代码.我真的应该给这个项目提供一个合适的许可证,这样,其他人可能更感兴趣,并在他们自己的项目中使用.不管怎样,但愿在这发布之后,我可以完成这件事.

在读完了这篇文章以及它链接的页面后,我受到了一些启发,决定为它编写我自己的模拟器,因为我有编写字节码引擎的经验.我计划着跟随这篇文章继续往前,先写一篇关于汇编器的文章,接下来是关于编译器的文章.这样,通过这些文章,你基本上可以学到,如何用Python为Cardiac创建编译工具集. 在简单CPU(simple-cpu)项目中,我已经编写了一个完整的可工作的汇编器.在内置的游戏中,已经有了可工作的编译器的最初步骤.我也选择Cardiac作为一个验证机器是因为它绝对的简单.不需要复杂的记忆,每个操作码只接受单一的参数,所以它是绝好的学习工具.此外,所有的数据参数都是相同的,不需要检测程序是需要一个寄存器,字符串或者还是内存地址.实际上,只有一个寄存器,累加器.因此,让我们开始吧!我们将基于类来创建,这样包含范围.如果你想尝试的话,你可以简单通过子类来增加新的操作码.首先,我们将集中于初始化例程.这个CPU非常简单,所以我们只需要初始化下面的内容: CPU寄存器, 操作码, 内存空间, 读卡器/输入, 和 打印/tty/输出.
 

class Cardiac(object): """ This class is the cardiac "CPU". """ def __init__(self):  self.init_cpu()  self.reset()  self.init_mem()  self.init_reader()  self.init_output() def reset(self):  """  This method resets the CPU's registers to their defaults.  """  self.pc = 0 #: Program Counter  self.ir = 0 #: Instruction Register  self.acc = 0 #: Accumulator  self.running = False #: Are we running? def init_cpu(self):  """  This fancy method will automatically build a list of our opcodes into a hash.  This enables us to build a typical case/select system in Python and also keeps  things more DRY. We could have also used the getattr during the process()  method before, and wrapped it around a try/except block, but that looks  a bit messy. This keeps things clean and simple with a nice one-to-one  call-map.   """  self.__opcodes = {}  classes = [self.__class__] #: This holds all the classes and base classes.  while classes:   cls = classes.pop() # Pop the classes stack and being   if cls.__bases__: # Does this class have any base classes?    classes = classes + list(cls.__bases__)   for name in dir(cls): # Lets iterate through the names.    if name[:7] == 'opcode_': # We only want opcodes here.     try:      opcode = int(name[7:])     except ValueError:      raise NameError('Opcodes must be numeric, invalid opcode: %s' % name[7:])     self.__opcodes.update({opcode:getattr(self, 'opcode_%s' % opcode)}) def init_mem(self):  """  This method resets the Cardiac's memory space to all blank strings, as per Cardiac specs.  """  self.mem = ['' for i in range(0,100)]  self.mem[0] = '001' #: The Cardiac bootstrap operation. def init_reader(self):  """  This method initializes the input reader.  """  self.reader = [] #: This variable can be accessed after initializing the class to provide input data. def init_output(self):  """  This method initializes the output deck/paper/printer/teletype/etc...  """  self.output = []            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表