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