#LYQ Y86-64 single_cycle-ISA
imem = [''] * 1000 #指令存储
dmem = [0] * 1000 #数据存储
reg = [0] * 15 #寄存器存储
reg[4] = 750 #rsp栈位置 取dmem中的一段作为栈空间
pReg = 0
iReg = ''
Stat = 1
#CC
ZF = 0
SF = 0
OF = 0
def get_V_D(instr):
return str(instr[14]+instr[15]+instr[12]+instr[13]+instr[10]+instr[11]+instr[8]+instr[9]+instr[6]+instr[7]+instr[4]+instr[5])
def get_Dest(instr):
return str(instr[12]+instr[13]+instr[10]+instr[11]+instr[8]+instr[9]+instr[6]+instr[7]+instr[4]+instr[5]+instr[2]+instr[3])
def loadProgram(file):
global pReg, iReg, reg, imem, dmem, Stat, ZF, SF, OF
fil = open(file, 'r')
first = True
while True:
line = fil.readline() # 指令+指令地址 (字符串)
if line == '':
break
fids = line.split() # 指令+指令地址 (列表)
address = int(fids[0],16) # 指令地址
instruc = fids[1] # 指令 (字符串)
imem[address] = instruc # 将指令存入imem
if first: # PC寄存器初始化
pReg = address
first = False
fil.close()
def cycle():
global pReg, iReg, reg, imem, dmem, Stat, ZF, SF, OF
# 取指令
iReg = imem[pReg] # 指令寄存器
pReg = pReg + 1 # PC寄存器
# 译码、执行和写结果
instr = list(iReg) # 指令(列表)
opcode = int(instr[0],16)
opfunction = int(instr[1],16)
if opcode == 0 : #halt
Stat = 2
elif opcode == 1 : #nop
1==1
elif opcode == 9 : #ret
pReg = dmem[reg[4]]
reg[4] = reg[4] + 8
else:
rA = int(instr[2],16)
rB = int(instr[3],16)
if opcode == 2 : #rrmovq rA,rB
reg[rB] = reg[rA]
elif opcode == 3 : #irmovq V,rB
V = int(get_V_D(instr),16)
reg[rB] = V
elif opcode == 4 : #rmmovq rA,D(rB)
D = int(get_V_D(instr),16)
dmem[D+rB] = reg[rA]
elif opcode == 5 : #mrmovq D(rB),rA
D = int(get_V_D(instr),16)
reg[rA] = dmem[D+rB]
elif opcode == 6 : #OPq rA,rB
fn = opfunction
if (fn==0): #addq
reg[rB] = reg[rB] + reg[rA]
elif (fn==1): #subq
reg[rB] = reg[rB] - reg[rA]
elif (fn==2): #andq
reg[rB] = reg[rB] & reg[rA]
elif (fn==3): #xorq
reg[rB] = reg[rB] ^ reg[rA]
#set CC
ZF = 1 if reg[rB] == 0 else 0
SF = 1 if reg[rB] < 0 else 0
elif opcode == 7: #jXX
fn = opfunction
Dest = int(get_Dest(instr),16)
if (fn==0): #jmp
pReg = Dest
elif (fn==1): #jle
if (SF^OF)|ZF:
pReg = Dest
elif (fn==2): #jl
if SF^OF:
pReg = Dest
elif (fn==3): #je
if ZF==1:
pReg = Dest
elif (fn==4): #jne
if ZF==0:
pReg = Dest
elif (fn==5): #jge
if (SF^OF)==0:
pReg = Dest
elif (fn==6): #jg
if ((SF^OF)==0)&(ZF==0):
pReg = Dest
elif opcode == 8: #call Dest
Dest = int(get_Dest(instr),16)
pReg = Dest
reg[4] = reg[4] - 8
dmem[reg[4]] = reg[rA]
elif opcode == 10: #pushq rA
reg[4] = reg[4] - 8
dmem[reg[4]] = reg[rA]
elif opcode == 11: #popq rA
reg[rA] = dmem[reg[4]]
reg[4] = reg[4] + 8
elif opcode == 15:
print("output:",reg[rA])
else:
Stat = 4
return True
def run(file):
global pReg, iReg, reg, imem, dmem, Stat, ZF, SF, OF
loadProgram(file)
while True:
cycle()
if Stat == 2:
print("HALT")
break
if Stat == 4:
print("INS")
break
run('1_100sigma.Y86_64')
'''
Appendix
***********************************************************************
1_100sigma Y86-64 assembly instruction
irmovq $1,%r8 //const
irmovq $1,%rsi //adder
irmovq $100,%r9 //counter
xorq %rax,%rax //result
loop:
addq %rsi,%rax
addq %r8,%rsi
subq %r8,%r9
jne loop
output %rax
halt
***********************************************************************
1_100sigma.Y86_64
0 30F80100000000000000 irmovq $1,%r8 //const
1 30F60100000000000000 irmovq $1,%rsi //adder
2 30F96400000000000000 irmovq $100,%r9 //counter
3 6300 xorq %rax,%rax //result
4 6060 addq %rsi,%rax loop
5 6086 addq %r8,%rsi
6 6189 subq %r8,%r9
7 740400000000000000 jne loop
8 F00F output %rax
9 00 halt
'''