From e4c1087290b4689a020a07dce2471a32ed086e14 Mon Sep 17 00:00:00 2001 From: root <1561515308@qq.com> Date: Mon, 29 Apr 2024 22:03:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=93=8D=E4=BD=9C=E7=A0=81?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ASM/Jump.py | 18 ++++++++++++++--- ASM/Logical.py | 31 +++++++++++++++++++++-------- ASM/Memory.py | 22 ++++++++++----------- ASM/count.py | 49 ++++++++++++++++++++++++++++++++++------------ ASM/debug.py | 18 ++--------------- CPU.py | 44 +++++++++++++++++++---------------------- Device/Codec.py | 7 +++++++ Example/加法器.txt | 8 ++++---- Memory.py | 14 ++++++++----- error.py | 17 +++++++++++++++- program.py | 5 +++-- 11 files changed, 146 insertions(+), 87 deletions(-) create mode 100644 Device/Codec.py diff --git a/ASM/Jump.py b/ASM/Jump.py index 0a6c242..e204180 100644 --- a/ASM/Jump.py +++ b/ASM/Jump.py @@ -1,10 +1,22 @@ +from error import * CMDs = ["jmp", "jmp_if"] def jmp(self, operand): - self.pc = int(operand[0]) + if operand[0].isImmediate(): + if operand[0].get() > len(self.cmdMemory): + raise AddressError() + self.pc = operand[0].get() + else: + raise BadOperand() def jmp_if(self, operand): - if int(operand[1]) == 1: - self.pc = int(operand[0]) + if operand[0].isImmediate(): + if operand[1].isImmediate() or operand[1].isRegister(): + if operand[0].get() > len(self.cmdMemory): + raise AddressError() + if operand[1].get() == 1: + self.pc = operand[0].get() + else: + raise BadOperand() diff --git a/ASM/Logical.py b/ASM/Logical.py index e6e0672..14ad74e 100644 --- a/ASM/Logical.py +++ b/ASM/Logical.py @@ -1,11 +1,26 @@ -CMDs = ["eq"] # , 'en', 'gt', 'lt', 'ge', 'le'] +CMDs = ["eq", 'halt'] # , 'en', 'gt', 'lt', 'ge', 'le'] +def CheckArg(operand): + run = False + if operand[0].isRegister(): + if operand[1].isRegister(): + run = True + elif operand[0].isRegister(): + if operand[1].isImmediate(): + run = True + else: + raise BadOperand() + return run def eq(self, operand): - # 是否等于 - a = self.registers[int(operand[0])] - b = self.registers[int(operand[1])] - if a == b: - self.registers[int(operand[2])] = 1 - else: - self.registers[int(operand[2])] = 0 + if CheckArg(operand) and operand[2].isRegister(): + # 是否等于 + a = operand[0].get() + b = operand[1].get + if a == b: + operand[2].set(1) + else: + operand[2].set(0) + +def halt(self, operand): + return False \ No newline at end of file diff --git a/ASM/Memory.py b/ASM/Memory.py index 70d7e77..163499e 100644 --- a/ASM/Memory.py +++ b/ASM/Memory.py @@ -1,21 +1,19 @@ # pylint:disable=W0622 +import program +from error import * + CMDs = ["ldr", "str"] -def ldr(self, operand): - print("从内存的", operand[1], "处加载至寄存器", operand[0]) - if int(operand[1]) < len(self.dtMemory): - value = self.dtMemory[int(operand[1])] - self.registers[int(operand[0])] = value +def ldr(self, operand:program.Operand): + if operand[0].isRegister() and operand[1].isMemory(): + operand[0].set(operand[1].get()) else: - print("ERROR: Attempted to load from invalid memory address.") + raise BadOperand() def str(self, operand): - # 往内存写入数据 - if int(operand[1]) < len(self.dtMemory): - value = self.registers[int(operand[0])] - print(value) - self.dtMemory[int(operand[1])] = value + if operand[0].isRegister() and operand[1].isMemory(): + operand[1].set(operand[0].get()) else: - print("ERROR: Attempted to store to invalid memory address.") + raise BadOperand() diff --git a/ASM/count.py b/ASM/count.py index 2d13d9f..251cd2b 100644 --- a/ASM/count.py +++ b/ASM/count.py @@ -1,20 +1,45 @@ +from error import * CMDs = ["add", "sub", "mul", "div"] - +def CheckArg(operand): + run = False + if operand[0].isRegister(): + if operand[1].isRegister(): + run = True + elif operand[0].isRegister(): + if operand[1].isImmediate(): + run = True + else: + raise BadOperand() + return run + def add(self, operand): - self.registers[int(operand[0])] += self.registers[int(operand[1])] - - + run = CheckArg(operand) + if run: + a = operand[0].get() + b = operand[1].get() + operand[0].set(a + b) + def sub(self, operand): - self.registers[int(operand[0])] -= self.registers[int(operand[1])] - + run = CheckArg(operand) + if run: + a = operand[0].get() + b = operand[1].get() + operand[0].set(a - b) + def mul(self, operand): - self.registers[int(operand[0])] *= self.registers[int(operand[1])] - + run = CheckArg(operand) + if run: + a = operand[0].get() + b = operand[1].get() + operand[0].set(a * b) + def div(self, operand): - if self.registers[int(operand[1])] != 0: - self.registers[int(operand[0])] //= self.registers[int(operand[1])] - else: - raise ZeroDivisionError() + run = CheckArg(operand) + if run: + a = operand[0].get() + b = operand[1].get() + operand[0].set(a // b) + \ No newline at end of file diff --git a/ASM/debug.py b/ASM/debug.py index 6b302f4..30c292a 100644 --- a/ASM/debug.py +++ b/ASM/debug.py @@ -1,19 +1,5 @@ -CMDs = ["prt", "prtr", "prtm"] +CMDs = ["prt"] def prt(self, operand): - print(operand[0]) - - -def prtr(self, operand): - if len(operand) > 0: - print(self.registers[int(operand[0])], end="") - else: - print(self.registers, end="") - - -def prtm(self, operand): - if len(operand) > 0: - print(self.dtMemory[int(operand[0])], end="") - else: - print(self.dtMemory, end="") + print(operand[0].get()) diff --git a/CPU.py b/CPU.py index 4ba5cd8..0168ac5 100644 --- a/CPU.py +++ b/CPU.py @@ -1,5 +1,6 @@ import queue from Memory import Memory +from error import * import pathlib import program import importlib @@ -34,7 +35,6 @@ class Core: def loadProgram(self, code): # 加载程序至cmdMemroy - print("加载长度为", len(code), "的程序") self.cmdMemory[: len(code)] = code def fetchInstruction(self): @@ -56,29 +56,26 @@ class Core: # 执行指令 if instruction is None: return False # 程序已执行完毕,返回False - + lists = instruction.split(" ") # 解析指令 opcode = lists[0] # 操作码 - operand = lists[1:] # 操作数 + operand = program.Operand(lists[1:], self) # 操作数 if opcode in self.ASMs: ins = getattr(self.ASMs[opcode], opcode) - ins(self, operand) - - if opcode == "prt": - # 调试函数,输出文字 - print(operand[0]) - - elif opcode == "halt": # HALT - # 结束 - return False - return True - - def write_to_memory(self, address, data): - # 往内存写入数据 - self.dtMemory[address] = data + ret = ins(self, operand) + if ret is None: + return True + elif ret is False: + return False + else: + return True + + else: + + raise InvalidInstruction() def run(self): # 开始执行 @@ -122,10 +119,9 @@ class CPU(Core): if __name__ == "__main__": cpu = CPU(registers=64, dtMemory=1024, cmdMemory=1024) program.Operand(["r0"], cpu)[0].set(2) - # f = open('Example/加法器.txt') - # code = f.read().split('\n') - # cpu.loadProgram(code) - cpu.write_to_memory(0, 1) - cpu.write_to_memory(1, 1) - # cpu.run() - print(cpu.registers[0]) + f = open('Example/加法器.txt') + code = f.read().split('\n') + cpu.loadProgram(code) + cpu.dtMemory.write_batch(0, [0, 1]) + cpu.run() + # print(cpu.registers[0]) diff --git a/Device/Codec.py b/Device/Codec.py new file mode 100644 index 0000000..af3ca56 --- /dev/null +++ b/Device/Codec.py @@ -0,0 +1,7 @@ +def byte2int(dt: bytes): + for i in dt: + yield i # 这将直接生成每个字节 + +def int2bytes(dt: list[int]): + for i in dt: + yield i.to_bytes(1, byteorder='big') # 将整数转换为字节 diff --git a/Example/加法器.txt b/Example/加法器.txt index e1c0652..605b6bc 100644 --- a/Example/加法器.txt +++ b/Example/加法器.txt @@ -1,5 +1,5 @@ -ldr 0 0 -ldr 1 1 -add 0 1 -prtr 0 +ldr r0 0x0 +ldr r1 0x1 +add r0 r1 +prt r0 halt \ No newline at end of file diff --git a/Memory.py b/Memory.py index 0234a68..ad60c20 100644 --- a/Memory.py +++ b/Memory.py @@ -8,11 +8,9 @@ class Memory: self.name = "内存" def init(self): - print("重置" + self.name) self.data = [0] * self.size def __getitem__(self, key: int): - print("读取位于", key, "的" + self.name) if key > self.size: raise AddressError return self.data[key] @@ -21,7 +19,15 @@ class Memory: if index > self.size: raise AddressError() self.data[index] = val - + + def write_batch(self, start ,dt:list[int]): + if start + len(dt) > self.size: + raise OutOfMemory('内存用尽') + + for i in dt: + self.write(start, i) + start += 1 + def __len__(self): return self.size @@ -29,8 +35,6 @@ class Memory: return str(self.data) def __setitem__(self, k, v): - print("写入位于", k, "的" + self.name) - if isinstance(k, slice): if not k.start: start = 0 diff --git a/error.py b/error.py index bca8fb4..c54ac3e 100644 --- a/error.py +++ b/error.py @@ -1,2 +1,17 @@ -class AddressError(Exception): +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 diff --git a/program.py b/program.py index 0602733..280c6ee 100644 --- a/program.py +++ b/program.py @@ -61,13 +61,14 @@ 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:1] == "0x": + elif i[0:2] == "0x": index = int(i, 16) self.List.append(MemoryArg(index, cpu)) elif i.isdigit(): self.List.append(ImmediateArg(int(i))) - + def __getitem__(self, key: int): return self.List[key]