From c56daff8028833ea6e3a15abd5c84b8c9817da33 Mon Sep 17 00:00:00 2001 From: root <1561515308@qq.com> Date: Thu, 2 May 2024 08:54:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ASM/Jump.py | 1 + ASM/Logical.py | 9 +++++--- ASM/Memory.py | 5 +++-- ASM/count.py | 13 ++++++----- CPU.py | 10 +++++---- Compiler.py | 51 +++++++++++++++++++++++++++++++++++++++++++ Device/Codec.py | 57 +++++++++++++++++++++++++++++++++++++++++++++---- Memory.py | 10 ++++----- error.py | 15 ++++++++----- program.py | 9 ++++++-- 10 files changed, 150 insertions(+), 30 deletions(-) create mode 100644 Compiler.py diff --git a/ASM/Jump.py b/ASM/Jump.py index e204180..6e72c7e 100644 --- a/ASM/Jump.py +++ b/ASM/Jump.py @@ -1,4 +1,5 @@ from error import * + CMDs = ["jmp", "jmp_if"] diff --git a/ASM/Logical.py b/ASM/Logical.py index 14ad74e..54653e8 100644 --- a/ASM/Logical.py +++ b/ASM/Logical.py @@ -1,4 +1,5 @@ -CMDs = ["eq", 'halt'] # , 'en', 'gt', 'lt', 'ge', 'le'] +CMDs = ["eq", "halt"] # , 'en', 'gt', 'lt', 'ge', 'le'] + def CheckArg(operand): run = False @@ -12,6 +13,7 @@ def CheckArg(operand): raise BadOperand() return run + def eq(self, operand): if CheckArg(operand) and operand[2].isRegister(): # 是否等于 @@ -21,6 +23,7 @@ def eq(self, operand): operand[2].set(1) else: operand[2].set(0) - + + def halt(self, operand): - return False \ No newline at end of file + return False diff --git a/ASM/Memory.py b/ASM/Memory.py index 163499e..0e72ebb 100644 --- a/ASM/Memory.py +++ b/ASM/Memory.py @@ -2,10 +2,10 @@ import program from error import * -CMDs = ["ldr", "str"] +CMDs = ["ldr", "str", 'ldrb'] -def ldr(self, operand:program.Operand): +def ldr(self, operand: program.Operand): if operand[0].isRegister() and operand[1].isMemory(): operand[0].set(operand[1].get()) else: @@ -17,3 +17,4 @@ def str(self, operand): operand[1].set(operand[0].get()) else: raise BadOperand() + diff --git a/ASM/count.py b/ASM/count.py index 251cd2b..f4653f8 100644 --- a/ASM/count.py +++ b/ASM/count.py @@ -1,6 +1,8 @@ from error import * + CMDs = ["add", "sub", "mul", "div"] + def CheckArg(operand): run = False if operand[0].isRegister(): @@ -12,21 +14,23 @@ def CheckArg(operand): else: raise BadOperand() return run - + + def add(self, operand): run = CheckArg(operand) if run: a = operand[0].get() b = operand[1].get() operand[0].set(a + b) - + + def sub(self, operand): run = CheckArg(operand) if run: a = operand[0].get() b = operand[1].get() operand[0].set(a - b) - + def mul(self, operand): run = CheckArg(operand) @@ -34,7 +38,7 @@ def mul(self, operand): a = operand[0].get() b = operand[1].get() operand[0].set(a * b) - + def div(self, operand): run = CheckArg(operand) @@ -42,4 +46,3 @@ def div(self, operand): a = operand[0].get() b = operand[1].get() operand[0].set(a // b) - \ No newline at end of file diff --git a/CPU.py b/CPU.py index 0168ac5..8e5ce6e 100644 --- a/CPU.py +++ b/CPU.py @@ -22,12 +22,14 @@ class Core: self.pc = 0 # 程序计数器 self.stack = queue.LifoQueue(maxsize=10 * self.registers.size) # 栈 - self.ASMModule = [] self.ASMs = {} for file in pathlib.Path("ASM").iterdir(): if file.is_dir(): continue + + if str(file).split('.')[-1] not in ['py', 'pyc', 'pyd', 'so']: + continue module = "ASM." + file.name.split(".")[0] module = importlib.import_module(module) for cmd in module.CMDs: @@ -35,7 +37,7 @@ class Core: def loadProgram(self, code): # 加载程序至cmdMemroy - self.cmdMemory[: len(code)] = code + self.cmdMemory.write_batch(0,code) def fetchInstruction(self): # 取指令 @@ -75,7 +77,7 @@ class Core: else: - raise InvalidInstruction() + raise InvalidInstruction(instruction) def run(self): # 开始执行 @@ -117,7 +119,7 @@ class CPU(Core): if __name__ == "__main__": - cpu = CPU(registers=64, dtMemory=1024, cmdMemory=1024) + cpu = CPU(registers=64, dtMemory=1024, cmdMemory=10) program.Operand(["r0"], cpu)[0].set(2) f = open('Example/加法器.txt') code = f.read().split('\n') diff --git a/Compiler.py b/Compiler.py new file mode 100644 index 0000000..ebea4e5 --- /dev/null +++ b/Compiler.py @@ -0,0 +1,51 @@ +from Device import Codec +import time +class Compiler: + def __init__(self, codes, filename='a.out'): + self.filename = filename + self.data = [] + + for i in codes: + self.data.append(Codec.str2int(i)) + + self.write() + + def write(self): + # 打开文件,以二进制写入模式打开 + with open(self.filename, 'wb') as f: + maxNum = max(self.data) + byte_representation = (maxNum.bit_length() + 7) // 8 + if byte_representation > 139: + raise MemoryError() + # 写入整数数据 + f.write(b'\x5a\xe3'+byte_representation.to_bytes(1, 'little')) + for num in self.data: + # 将整数转换为字节,并写入文件 + f.write(num.to_bytes(byte_representation , 'little')) # 假设每个整数都用4个字节表示 + + def read(self): + int_data_read = [] # 用于存储读取的整数数据 + + # 打开文件,以二进制读取模式打开 + with open(self.filename, 'rb') as f: + # 读取整数数据 + MagicNumber = f.read(2) + + size = int.from_bytes(f.read(1), 'little') + while True: + # 从文件中读取4个字节,并将其转换为整数 + int_bytes = f.read(size) + + if not int_bytes: # 如果读取完整个文件,则退出循环 + break + int_value = int.from_bytes(int_bytes, 'little') # 假设之前用little-endian序列化 + int_value = Codec.int2list(int_value) + + int_value = Codec.int2str(int_value) + int_data_read.append(int_value) + + return int_data_read +start = time.time() +c = Compiler(["l","h",'kakshdhsh sjjsvav']) +print(time.time()-start) +print(list(c.read())) \ No newline at end of file diff --git a/Device/Codec.py b/Device/Codec.py index af3ca56..72cfb44 100644 --- a/Device/Codec.py +++ b/Device/Codec.py @@ -1,7 +1,56 @@ -def byte2int(dt: bytes): +from functools import lru_cache +import math +def str2int(dt: str): + a = [] + maxInt = 0 + # 遍历输入的字符串 for i in dt: - yield i # 这将直接生成每个字节 + # 使用ord函数将每个字符转换为对应的ASCII码,生成整数流 + this = ord(i) + if this >maxInt: + maxInt = this + a.append(str(this)) + IntSize = len(str(maxInt)) + out = str(IntSize) + for i in a: + i.zfill(IntSize) + # 将处理后的整数字符串添加到输出字符串中 + out += i + return int(out) -def int2bytes(dt: list[int]): +def int2str(dt: list[int]): + # 遍历整数列表 + a = [] for i in dt: - yield i.to_bytes(1, byteorder='big') # 将整数转换为字节 + # 使用chr函数将每个整数转换为对应的字符,生成字节流 + a.append(chr(i)) + return a + +def list2int(dt: list[str]): + # 防止第一个数为零 + maxInt = max(dt) + IntSize = len(str(maxInt)) + out = str(IntSize) + + # 遍历整数列表 + for i in dt: + # 将整数转换为字符串 + i = str(i) + # 如果字符串长度小于3,则在前面补0,使其长度为3 + if len(i) < IntSize: + while len(i) < IntSize: + i = '0' + i + # 将处理后的整数字符串添加到输出字符串中 + out += i + # 将结果字符串转换为整数并返回 + return int(out) + +def int2list(dt: int): + # 将整数转换为字符串,并去掉前面的'100' + size = int(str(dt)[0]) + dt = str(dt)[1:] + # 将字符串按照每3个字符分割为子列表 + sub_lists = [dt[i:i+size] for i in range(0, len(dt), size)] + # 遍历子列表并将其转换为整数后返回 + for i in sub_lists: + yield int(i) \ No newline at end of file diff --git a/Memory.py b/Memory.py index ad60c20..8e7387f 100644 --- a/Memory.py +++ b/Memory.py @@ -19,15 +19,15 @@ class Memory: if index > self.size: raise AddressError() self.data[index] = val - - def write_batch(self, start ,dt:list[int]): + + def write_batch(self, start, dt: list[int]): if start + len(dt) > self.size: - raise OutOfMemory('内存用尽') - + raise OutOfMemory("内存用尽") + for i in dt: self.write(start, i) start += 1 - + def __len__(self): return self.size diff --git a/error.py b/error.py index c54ac3e..3a8c3e9 100644 --- a/error.py +++ b/error.py @@ -1,17 +1,22 @@ class dtMemoryError(Exception): pass - + + class AddressError(dtMemoryError): pass + class OutOfMemory(dtMemoryError): pass - + + class InstructionError(Exception): pass - + + class InvalidInstruction(InstructionError): pass - + + class BadOperand(InstructionError): - pass \ No newline at end of file + pass diff --git a/program.py b/program.py index 280c6ee..7b82635 100644 --- a/program.py +++ b/program.py @@ -4,6 +4,11 @@ from error import * class Program: def __init__(self, code: str): self.codelist = code.split("\n") + self.res = [] + def parser(self): + for i in self.codelist: + print(i) + class BaseArg: @@ -61,7 +66,7 @@ class Operand: def __init__(self, operList, cpu): self.List = [] for i in operList: - + if i[0] == "r": self.List.append(RegisterArg(int(i[1:]), cpu)) elif i[0:2] == "0x": @@ -69,6 +74,6 @@ class Operand: self.List.append(MemoryArg(index, cpu)) elif i.isdigit(): self.List.append(ImmediateArg(int(i))) - + def __getitem__(self, key: int): return self.List[key]