269 lines
6.2 KiB
Python
Executable File
269 lines
6.2 KiB
Python
Executable File
#encoding=utf-8
|
|
# reg file
|
|
reg = {
|
|
'rax':0,
|
|
'rcx':0,
|
|
'rdx':0,
|
|
'rbx':0,
|
|
|
|
'rsp':0,
|
|
'rbp':0,
|
|
'rsi':0,
|
|
'rdi':0,
|
|
|
|
'r8' :0,
|
|
'r9' :0,
|
|
'r10':0,
|
|
'r11':0,
|
|
|
|
'r12':0,
|
|
'r13':0,
|
|
'r14':0,
|
|
}
|
|
|
|
# 读取可执行文件
|
|
def read_exe_file(path):
|
|
infile = open(path)
|
|
file = infile.readlines()[2:]
|
|
return file
|
|
|
|
# 名称转换
|
|
def get_reg(s):
|
|
s = s.upper()
|
|
reg_name = {
|
|
'0':'rax',
|
|
'1':'rcx',
|
|
'2':'rdx',
|
|
'3':'rbx',
|
|
|
|
'4':'rsp',
|
|
'5':'rbp',
|
|
'6':'rsi',
|
|
'7':'rdi',
|
|
|
|
'8':'r8' ,
|
|
'9':'r9' ,
|
|
'A':'r10',
|
|
'B':'r11',
|
|
|
|
'C':'r12',
|
|
'D':'r13',
|
|
'E':'r14',
|
|
'F':None
|
|
}
|
|
return reg_name[s]
|
|
|
|
# 小端数据处理
|
|
def data_reverse(data):
|
|
return int(''.join([data[i:i+2] for i in range(16,-2,-2)]),16)
|
|
|
|
# 标志处理
|
|
def flags(result):
|
|
global zf,sf,of
|
|
if result == 0:
|
|
zf = 1
|
|
else:
|
|
zf = 0
|
|
if result < 0:
|
|
sf = 1
|
|
else:
|
|
sf = 0
|
|
if result > 4294967296 or result < -4294967296: #溢出
|
|
of = 1
|
|
else:
|
|
of = 0
|
|
|
|
# 标志位
|
|
zf = 0
|
|
sf = 0
|
|
of = 0
|
|
|
|
pc = 0
|
|
stat = 0
|
|
|
|
mem = [0 for i in range(101)]
|
|
reg['rsp'] = 100
|
|
try:
|
|
exe_file = read_exe_file("./Y86_instr.coe")
|
|
if len(exe_file) < 1:
|
|
exit()
|
|
except FileNotFoundError:
|
|
print(f"FileNotFoundError: {"./Y86_instr.coe"} not found, the progarm will use internal exe_file stored in this python code")
|
|
#exe_file:
|
|
#0 irmovq $1,%rax 30f001000000
|
|
#1 irmovq $1,%r8 30f801000000
|
|
#2 irmovq $0,%rbx 30f300000000
|
|
#3 irmovq $100,%rdx 30f264000000
|
|
#loop:
|
|
#4 subq %rax,%rdx 6102
|
|
#5 jl then 720a000000
|
|
#6 irmovq $100,%rdx 30f264000000
|
|
#7 addq %rax,%rbx 6003
|
|
#8 addq %r8,%rax 6080
|
|
#9 jmp loop 7004000000
|
|
#then:
|
|
#10 rmmovq %rbx,0(%rsp) 403400000000
|
|
exe_file = ['30f001000000',
|
|
'30f801000000',
|
|
'30f300000000',
|
|
'30f264000000',
|
|
'6102',
|
|
'720a000000',
|
|
'30f264000000',
|
|
'6003',
|
|
'6080',
|
|
'7004000000',
|
|
'403400000000',
|
|
]
|
|
|
|
# 主循环
|
|
def cycle():
|
|
global pc
|
|
s = exe_file[pc]
|
|
ins = s[0]
|
|
fn = s[1]
|
|
if ins == '0': # halt
|
|
print("instr \'halt\' is not allowed to be used by application")
|
|
return False
|
|
elif ins == '1': # nop
|
|
pc += 1
|
|
elif ins == '2': # mov
|
|
ra = get_reg(s[2])
|
|
rb = get_reg(s[3])
|
|
if fn == '0': # rrmovq
|
|
reg[rb] = reg[ra]
|
|
elif fn == '1': # cmovle
|
|
if (sf ^ of) | zf:
|
|
reg[rb] = reg[ra]
|
|
elif fn == '2': # cmovl
|
|
if sf ^ of:
|
|
reg[rb] = reg[ra]
|
|
elif fn == '3': # cmove
|
|
if zf:
|
|
reg[rb] = reg[ra]
|
|
elif fn == '4': #cmovne
|
|
if ~zf:
|
|
reg[rb] = reg[ra]
|
|
elif fn == '5': #cmovge
|
|
if ~(sf ^ of):
|
|
reg[rb] = reg[ra]
|
|
elif fn == '6': #cmovg
|
|
if ~(sf ^ of) & ~ zf:
|
|
reg[rb] = reg[ra]
|
|
pc += 1
|
|
elif ins == '3': # irmovq
|
|
ra = None
|
|
rb = get_reg(s[3])
|
|
data = data_reverse(s[4:])
|
|
reg[rb] = data
|
|
pc += 1
|
|
elif ins == '4': # rmmovq
|
|
ra = get_reg(s[2])
|
|
rb = get_reg(s[3])
|
|
data = reg[ra]
|
|
mem[reg[rb]] = data
|
|
pc += 1
|
|
elif ins == '5': # mrmovq
|
|
ra = get_reg(s[2])
|
|
rb = get_reg(s[3])
|
|
data = mem[reg[rb]]
|
|
reg[ra] = data
|
|
pc += 1
|
|
elif ins == '6': # OPq
|
|
ra = get_reg(s[2])
|
|
rb = get_reg(s[3])
|
|
if fn == '0':
|
|
reg[rb] = reg[rb] + reg[ra]
|
|
elif fn == '1':
|
|
reg[rb] = reg[rb] - reg[ra]
|
|
elif fn == '2':
|
|
reg[rb] = reg[rb] & reg[ra]
|
|
elif fn == '3':
|
|
reg[rb] = reg[rb] ^ reg[ra]
|
|
flags(reg[rb])
|
|
pc += 1
|
|
elif ins == '7': #jXX
|
|
dst = data_reverse(s[2:])
|
|
if fn =='0': # jmp
|
|
pc = dst
|
|
elif fn =='1': #jle
|
|
if (sf ^ of) | zf:
|
|
pc = dst
|
|
else:
|
|
pc += 1
|
|
elif fn =='2': #jl
|
|
if sf ^ of:
|
|
pc = dst
|
|
else:
|
|
pc += 1
|
|
elif fn =='3': #je
|
|
if zf:
|
|
pc = dst
|
|
else:
|
|
pc += 1
|
|
elif fn =='4': #jne
|
|
if ~zf:
|
|
pc = dst
|
|
else:
|
|
pc += 1
|
|
elif fn =='5': #jge
|
|
if ~(sf ^ of):
|
|
pc = dst
|
|
else:
|
|
pc += 1
|
|
elif fn =='6': #jg
|
|
if ~(sf ^ of) & ~ zf:
|
|
pc = dst
|
|
else:
|
|
pc += 1
|
|
elif ins == '8': #call
|
|
dst = data_reverse(s[2:])
|
|
reg['rsp'] -= 1
|
|
mem[reg['rsp']] = pc + 1
|
|
pc = dst
|
|
elif ins == '9': # ret
|
|
pc = mem[reg['rsp']]
|
|
reg['rsp'] += 1
|
|
elif ins == 'A': # pushq
|
|
ra = get_reg(s[3])
|
|
rb = get_reg(s[4])
|
|
reg['rsp'] -= 1
|
|
mem[reg['rsp']] = reg[ra]
|
|
pc += 1
|
|
elif ins == 'B': # popq
|
|
ra = get_reg(s[3])
|
|
rb = get_reg(s[4])
|
|
reg[ra] = mem[reg['rsp']]
|
|
reg['rsp'] += 1
|
|
pc += 1
|
|
return True
|
|
|
|
# 打印寄存器文件
|
|
|
|
def print_reg():
|
|
print('-'*20+"reg file"+'-'*20)
|
|
i = 0
|
|
for reg_name in reg.keys():
|
|
print("%s:%d"%(reg_name,reg[reg_name]),end='\t')
|
|
i += 1
|
|
if i % 4 == 0 or reg_name == 'r14':
|
|
print()
|
|
print('-'*20+"end"+'-'*20)
|
|
def print_mem():
|
|
print('-'*20+"mem"+'-'*20)
|
|
print('address:value')
|
|
j = 0
|
|
for i in range(len(mem)):
|
|
print("%d:%d"%(i,mem[i]),end=' ')
|
|
j += 1
|
|
if j % 16 == 0:
|
|
print()
|
|
print('\n'+'-'*20+"end"+'-'*20)
|
|
|
|
# start
|
|
flag = True
|
|
while flag and pc < len(exe_file):
|
|
flag = cycle()
|
|
print_mem()
|
|
print_reg()
|