#初始化
def init():
########## Begin ##########
mem =[0]*1000 # 主存
reg =[0]*10 # 通用寄存器
pReg =0 # 程序计数器
iReg =0 # 指令寄存器
res =0 # 存放输出结果
########## End ##########
print(mem,reg,pReg,iReg)
第2关:程序加载
#程序加载
def loadProgram(file, mem, address):
########## Begin ##########
txt =open(file,'r')
s = txt.readlines()for x in s :
l =len(x)
bg, L =0,[]while bg <= l -1:
mdl =''
flag = False
while x[bg]!=' ':
mdl = mdl + x[bg]
bg +=1if bg == l -1:
flag = True
breakwhile x[bg]==' ':if bg == l -1:
flag = True
break
bg +=1
L.append(mdl)if flag :break#L
L.pop(0)
mem[address]=' '.join(L)
address = address +1
########## End ##########
print(mem)
第3关:取指令
#取指令:根据程序计数器给出的地址取出主存对应的指令放入指令寄存器
def fetch(mem, pReg):
########## Begin ##########
iReg = mem[pReg]
pReg = pReg +1
########## End ##########
print(iReg)return pReg, iReg
第4关:指令译码
#指令译码:解析指令寄存器中的指令
def decode(iReg):
########## Begin ##########
l =len(iReg)
cnt, i =0,0
L =[]while i < l :while i < l and iReg[i]==' ':
i = i +1if i == l :break;
cnt = cnt +1; mdl =''while i < l and iReg[i]!=' ':
mdl = mdl + iReg[i]
i = i +1if cnt >1:
bg =0while bg <len(mdl) and mdl[bg]=='0':
bg = bg +1
mdl = mdl[bg :]
L.append(mdl)while cnt <3:
L.append('None')
cnt = cnt +1
ret ='('+"'"+ L[0]+"'"+','+' '+ L[1]+','+' '+ L[2]+')'return ret
########## End ##########
第5关:指令执行
#执行和写结果
def execute(opcode, op1, op2, reg, mem, pReg):
########## Begin ##########
global iReg
if opcode =='mov1':
reg[op1]=eval(mem[op2])
result = reg[op1]
elif opcode =='mov2':
mem[op1]=str(reg[op2])
result = mem[op1]
elif opcode =='mov3':
reg[op1]= op2
result = reg[op1]
elif opcode =='add':
reg[op1]+= reg[op2]
result = reg[op1]
elif opcode =='sub':
reg[op1]-= reg[op2]
result = reg[op1]
elif opcode =='mul':
reg[op1]*= reg[op2]
result = reg[op1]
elif opcode =='div':
reg[op1]= reg[op1]// reg[op2]
result = reg[op1]
elif opcode =='jmp':
iReg = mem[op1]#pReg =eval(mem[op1])return pReg
elif opcode =='jz':if reg[op1]==0:#pReg =eval(mem[op2]
iReg = mem[op2]
result = pReg
elif opcode =='in':
reg[op1]=eval(input())
result = reg[op1]
elif opcode =='out':#print(reg[op1])
result = reg[op1]else:
result = False
########## End ##########
return result
第6关:TOY计算机执行程序的完整过程
#模拟 CPU 执行完整程序代码的全部过程
#初始化主存、通用寄存器、指令寄存器和程序计数器
mem =['']*1000 #主存
reg =[0]*10 #通用寄存器
pReg =0 #程序计数器
iReg ='' #指令寄存器
#程序加载:从主存mem的address地址开始存放file文件
def loadProgram(file, mem, address):
########## Begin ##########
txt =open(file,'r')
s = txt.readlines()for x in s :
l =len(x)
bg, L =0,[]while bg < l :
mdl =''while bg < l and x[bg]!=' ':
mdl = mdl + x[bg]
bg +=1while bg < l and x[bg]==' ':
bg +=1
L.append(mdl)
L.pop(0)
mem[address]=' '.join(L)
address = address +1
########## End ##########
#取指令:根据程序计数器给出的地址取出主存对应的指令放入指令寄存器
def fetch(mem, pReg):
########## Begin ##########
iReg = mem[pReg]
########## End ##########
return pReg, iReg
#指令译码:解析指令寄存器中的指令,不存在的操作数置为None
def decode(iReg):
########## Begin ##########
l =len(iReg)
cnt, i =0,0
L =[]while i < l :while i < l and iReg[i]==' ':
i = i +1if i == l :break
cnt = cnt +1; mdl =''while i < l and iReg[i]!=' ':
mdl = mdl + iReg[i]
i = i +1if cnt >1:
bg =0while bg <len(mdl) and mdl[bg]=='0':
bg = bg +1
mdl = mdl[bg :]
L.append(mdl)
tmp = cnt
while cnt <3:
L.append('None')
cnt = cnt +1if tmp ==1:return L[0],0,0
elif tmp ==2:if L[1]=='' or L[1]=='\n':return L[0],0,0return L[0],eval(L[1]),0else:
ret1, ret2 =0,0if L[1]!='' and L[1]!='\n':
ret1 =eval(L[1])if L[2]!='' and L[2]!='\n':
ret2 =eval(L[2])return L[0], ret1, ret2
########## End ##########
return opcode,op1,op2 #opcode为操作码,op1为第一个操作数,op2为第二个操作数
#执行和写结果:根据指令解析的操作码执行对应的操作,若为停机指令返回 False,其余指令返回 True
##opcode为操作码,op1为第一个操作数,op2为第二个操作数
#reg为通用寄存器,mem为主存,address为程序第一条指令在主存中的地址
def execute(opcode, op1, op2, reg, mem, address):
global pReg
########## Begin ##########
global pReg
flag = False
if opcode =='mov1':
reg[op1]=eval(mem[op2])
elif opcode =='mov2':
mem[op1]=str(reg[op2])
elif opcode =='mov3':
reg[op1]= op2
elif opcode =='add':
reg[op1]+= reg[op2]
elif opcode =='sub':
reg[op1]-= reg[op2]
elif opcode =='mul':
reg[op1]*= reg[op2]
elif opcode =='div':
reg[op1]= reg[op1]// reg[op2]
elif opcode =='jmp':
iReg = mem[op1]
pReg = op1 + address
flag = True
elif opcode =='jz':if reg[op1]==0:
flag = True
iReg = mem[op2]
pReg = op2 + address
elif opcode =='in':
reg[op1]=eval(input())
elif opcode =='out':print(reg[op1])if flag == False :
pReg = pReg +1if opcode !='halt' and opcode !='halt\n':
result = True
else:
result = False
return result
########## End ##########
#完整过程模拟:程序加载、取指令、指令译码、指令执行和写结果
def run(file, addr):
global pReg, iReg
########BEGIN########
pReg = addr
loadProgram(file, mem, addr)while True :
pReg, iReg =fetch(mem, pReg)
L, op1, op2 =decode(iReg)
mdl =execute(L, op1, op2, reg, mem, addr)if mdl == False :break
########## End ##########
file =input() #获取TOY程序代码存放的文件名字
address =int(input()) #获取TOY程序第一条代码加载到的主存物理地址
run(file, address) #加载TOY程序到主存指定地址,并执行
第7关:扩展 TOY 计算机指令集
def init():
global mem,reg,pReg,iReg,CF
########## Begin ##########
mem =['']*1000 #主存
reg =[0]*10 #通用寄存器
pReg =0 #程序计数器
iReg ='' #指令寄存器
CF =0
def loadProgram(file, mem, address):
txt =open(file,'r')
s = txt.readlines()for x in s :
l =len(x)
bg, L =0,[]while bg < l :
mdl =''while bg < l and x[bg]!=' ' and x[bg]!='\t':
mdl = mdl + x[bg]
bg +=1while bg < l and(x[bg]==' ' or x[bg]=='\t'):
bg +=1
L.append(mdl)
L.pop(0)
mem[address]=' '.join(L)
address = address +1
#取指令:根据程序计数器给出的地址取出主存对应的指令放入指令寄存器
def fetch():
global mem, pReg, iReg
iReg = mem[pReg]return pReg, iReg
#指令译码:解析指令寄存器中的指令,不存在的操作数置为None
def decode():
global iReg
l =len(iReg)
cnt, i =0,0
L =[]while i < l :while i < l and iReg[i]==' ':
i = i +1if i == l :break
cnt = cnt +1; mdl =''while i < l and iReg[i]!=' ':
mdl = mdl + iReg[i]
i = i +1if cnt >1:
bg =0while bg <len(mdl) and mdl[bg]=='0':
bg = bg +1
mdl = mdl[bg :]
L.append(mdl)
tmp = cnt
while cnt <3:
L.append('None')
cnt = cnt +1if tmp ==1:return L[0],0,0
elif tmp ==2:if L[1]=='' or L[1]=='\n':return L[0],0,0return L[0],eval(L[1]),0else:
ret1, ret2 =0,0if L[1]!='' and L[1]!='\n':
ret1 =eval(L[1])if L[2]!='' and L[2]!='\n':
ret2 =eval(L[2])return L[0], ret1, ret2
########## End ##########
#执行和写结果:根据指令解析的操作码执行对应的操作,若为停机指令返回 False,其余指令返回 True
##opcode为操作码,op1为第一个操作数,op2为第二个操作数
def execute(opcode,op1,op2, address):
global reg, pReg, CF, mem
flag = False
if opcode =='mov1':
reg[op1]=eval(mem[op2])
elif opcode =='mov2':
mem[op1]=str(reg[op2])
elif opcode =='mov3':
reg[op1]= op2
elif opcode =='add':
reg[op1]+= reg[op2]
elif opcode =='sub':
reg[op1]-= reg[op2]
elif opcode =='mul':
reg[op1]*= reg[op2]
elif opcode =='div':
reg[op1]= reg[op1]// reg[op2]
elif opcode =='jmp':
iReg = mem[op1]
pReg = op1 + address
flag = True
elif opcode =='jz':if reg[op1]==0:
flag = True
iReg = mem[op2]
pReg = op2 + address
elif opcode =='in':
reg[op1]=eval(input())
elif opcode =='out':print(reg[op1])
elif opcode =='add2':
reg[op1]+= op2
elif opcode =='cmp':if reg[op1]<= op2 :
CF =1else:
CF =0
elif opcode =='ble':if CF :
pReg = reg[op1]+ address
flag = True
if flag == False :
pReg = pReg +1if opcode !='halt' and opcode !='halt\n':
result = True
else:
result = False
########## End ##########
return result
#完整过程模拟:程序加载、取指令、指令译码、指令执行和写结果
def run(file, addr):
global pReg, iReg, reg
######## Begin ########
pReg = addr
loadProgram(file, mem, addr)while True :
pReg, iReg =fetch()
L, op1, op2 =decode()
mdl =execute(L, op1, op2, addr)if mdl == False :break
########## End ##########