增加操作码类

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"]
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()

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):
# 是否等于
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

View File

@ -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()

View File

@ -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)

View File

@ -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())

38
CPU.py
View File

@ -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):
@ -61,24 +61,21 @@ class Core:
# 解析指令
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)
ret = ins(self, operand)
if ret is None:
return True
elif ret is False:
return False
else:
return True
if opcode == "prt":
# 调试函数,输出文字
print(operand[0])
else:
elif opcode == "halt": # HALT
# 结束
return False
return True
def write_to_memory(self, address, data):
# 往内存写入数据
self.dtMemory[address] = data
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])

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 1 1
add 0 1
prtr 0
ldr r0 0x0
ldr r1 0x1
add r0 r1
prt r0
halt

View File

@ -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]
@ -22,6 +20,14 @@ class Memory:
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

View File

@ -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

View File

@ -61,9 +61,10 @@ 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():