增加操作码类

This commit is contained in:
root 2024-04-29 22:03:14 +08:00
parent d010ed5f9c
commit e4c1087290
11 changed files with 146 additions and 87 deletions

View File

@ -1,10 +1,22 @@
from error import *
CMDs = ["jmp", "jmp_if"] CMDs = ["jmp", "jmp_if"]
def jmp(self, operand): 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): def jmp_if(self, operand):
if int(operand[1]) == 1: if operand[0].isImmediate():
self.pc = int(operand[0]) 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()

View File

@ -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): def eq(self, operand):
# 是否等于 if CheckArg(operand) and operand[2].isRegister():
a = self.registers[int(operand[0])] # 是否等于
b = self.registers[int(operand[1])] a = operand[0].get()
if a == b: b = operand[1].get
self.registers[int(operand[2])] = 1 if a == b:
else: operand[2].set(1)
self.registers[int(operand[2])] = 0 else:
operand[2].set(0)
def halt(self, operand):
return False

View File

@ -1,21 +1,19 @@
# pylint:disable=W0622 # pylint:disable=W0622
import program
from error import *
CMDs = ["ldr", "str"] CMDs = ["ldr", "str"]
def ldr(self, operand): def ldr(self, operand:program.Operand):
print("从内存的", operand[1], "处加载至寄存器", operand[0]) if operand[0].isRegister() and operand[1].isMemory():
if int(operand[1]) < len(self.dtMemory): operand[0].set(operand[1].get())
value = self.dtMemory[int(operand[1])]
self.registers[int(operand[0])] = value
else: else:
print("ERROR: Attempted to load from invalid memory address.") raise BadOperand()
def str(self, operand): def str(self, operand):
# 往内存写入数据 if operand[0].isRegister() and operand[1].isMemory():
if int(operand[1]) < len(self.dtMemory): operand[1].set(operand[0].get())
value = self.registers[int(operand[0])]
print(value)
self.dtMemory[int(operand[1])] = value
else: else:
print("ERROR: Attempted to store to invalid memory address.") raise BadOperand()

View File

@ -1,20 +1,45 @@
from error import *
CMDs = ["add", "sub", "mul", "div"] 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): 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): 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): 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): def div(self, operand):
if self.registers[int(operand[1])] != 0: run = CheckArg(operand)
self.registers[int(operand[0])] //= self.registers[int(operand[1])] if run:
else: a = operand[0].get()
raise ZeroDivisionError() b = operand[1].get()
operand[0].set(a // b)

View File

@ -1,19 +1,5 @@
CMDs = ["prt", "prtr", "prtm"] CMDs = ["prt"]
def prt(self, operand): def prt(self, operand):
print(operand[0]) print(operand[0].get())
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="")

44
CPU.py
View File

@ -1,5 +1,6 @@
import queue import queue
from Memory import Memory from Memory import Memory
from error import *
import pathlib import pathlib
import program import program
import importlib import importlib
@ -34,7 +35,6 @@ class Core:
def loadProgram(self, code): def loadProgram(self, code):
# 加载程序至cmdMemroy # 加载程序至cmdMemroy
print("加载长度为", len(code), "的程序")
self.cmdMemory[: len(code)] = code self.cmdMemory[: len(code)] = code
def fetchInstruction(self): def fetchInstruction(self):
@ -56,29 +56,26 @@ class Core:
# 执行指令 # 执行指令
if instruction is None: if instruction is None:
return False # 程序已执行完毕返回False return False # 程序已执行完毕返回False
lists = instruction.split(" ") lists = instruction.split(" ")
# 解析指令 # 解析指令
opcode = lists[0] # 操作码 opcode = lists[0] # 操作码
operand = lists[1:] # 操作数 operand = program.Operand(lists[1:], self) # 操作数
if opcode in self.ASMs: if opcode in self.ASMs:
ins = getattr(self.ASMs[opcode], opcode) ins = getattr(self.ASMs[opcode], opcode)
ins(self, operand) ret = ins(self, operand)
if ret is None:
if opcode == "prt": return True
# 调试函数,输出文字 elif ret is False:
print(operand[0]) return False
else:
elif opcode == "halt": # HALT return True
# 结束
return False else:
return True
raise InvalidInstruction()
def write_to_memory(self, address, data):
# 往内存写入数据
self.dtMemory[address] = data
def run(self): def run(self):
# 开始执行 # 开始执行
@ -122,10 +119,9 @@ class CPU(Core):
if __name__ == "__main__": if __name__ == "__main__":
cpu = CPU(registers=64, dtMemory=1024, cmdMemory=1024) cpu = CPU(registers=64, dtMemory=1024, cmdMemory=1024)
program.Operand(["r0"], cpu)[0].set(2) program.Operand(["r0"], cpu)[0].set(2)
# f = open('Example/加法器.txt') f = open('Example/加法器.txt')
# code = f.read().split('\n') code = f.read().split('\n')
# cpu.loadProgram(code) cpu.loadProgram(code)
cpu.write_to_memory(0, 1) cpu.dtMemory.write_batch(0, [0, 1])
cpu.write_to_memory(1, 1) cpu.run()
# cpu.run() # print(cpu.registers[0])
print(cpu.registers[0])

7
Device/Codec.py Normal file
View File

@ -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') # 将整数转换为字节

View File

@ -1,5 +1,5 @@
ldr 0 0 ldr r0 0x0
ldr 1 1 ldr r1 0x1
add 0 1 add r0 r1
prtr 0 prt r0
halt halt

View File

@ -8,11 +8,9 @@ class Memory:
self.name = "内存" self.name = "内存"
def init(self): def init(self):
print("重置" + self.name)
self.data = [0] * self.size self.data = [0] * self.size
def __getitem__(self, key: int): def __getitem__(self, key: int):
print("读取位于", key, "" + self.name)
if key > self.size: if key > self.size:
raise AddressError raise AddressError
return self.data[key] return self.data[key]
@ -21,7 +19,15 @@ class Memory:
if index > self.size: if index > self.size:
raise AddressError() raise AddressError()
self.data[index] = val 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): def __len__(self):
return self.size return self.size
@ -29,8 +35,6 @@ class Memory:
return str(self.data) return str(self.data)
def __setitem__(self, k, v): def __setitem__(self, k, v):
print("写入位于", k, "" + self.name)
if isinstance(k, slice): if isinstance(k, slice):
if not k.start: if not k.start:
start = 0 start = 0

View File

@ -1,2 +1,17 @@
class AddressError(Exception): class dtMemoryError(Exception):
pass pass
class AddressError(dtMemoryError):
pass
class OutOfMemory(dtMemoryError):
pass
class InstructionError(Exception):
pass
class InvalidInstruction(InstructionError):
pass
class BadOperand(InstructionError):
pass

View File

@ -61,13 +61,14 @@ class Operand:
def __init__(self, operList, cpu): def __init__(self, operList, cpu):
self.List = [] self.List = []
for i in operList: for i in operList:
if i[0] == "r": if i[0] == "r":
self.List.append(RegisterArg(int(i[1:]), cpu)) self.List.append(RegisterArg(int(i[1:]), cpu))
elif i[0:1] == "0x": elif i[0:2] == "0x":
index = int(i, 16) index = int(i, 16)
self.List.append(MemoryArg(index, cpu)) self.List.append(MemoryArg(index, cpu))
elif i.isdigit(): elif i.isdigit():
self.List.append(ImmediateArg(int(i))) self.List.append(ImmediateArg(int(i)))
def __getitem__(self, key: int): def __getitem__(self, key: int):
return self.List[key] return self.List[key]