Add label processing to disassembler
This commit is contained in:
parent
81039ce304
commit
d8f472a31f
91
disasm.py
91
disasm.py
@ -21,11 +21,61 @@ import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('file', help='.bin file containing the initial memory dump')
|
||||
parser.add_argument('--hints', help='File(s) outlining additional jmp/call targets, label names, comments, etc', action='append')
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.file, 'rb') as data:
|
||||
SYN_MEM = memory_from_file(data)
|
||||
|
||||
# Find things to label
|
||||
labels, comments_before, comments_inline = {}, {}, {}
|
||||
SYN_PTR = 0
|
||||
while SYN_PTR < len(SYN_MEM):
|
||||
word = SYN_MEM[SYN_PTR]
|
||||
if word in instructions_by_opcode:
|
||||
instruction, SYN_PTR = Instruction.next_instruction(SYN_MEM, SYN_PTR)
|
||||
if isinstance(instruction, InstructionJmp) or isinstance(instruction, InstructionJt) or isinstance(instruction, InstructionJf):
|
||||
if isinstance(instruction, InstructionJmp):
|
||||
op = instruction.args[0]
|
||||
else:
|
||||
op = instruction.args[1]
|
||||
if isinstance(op, OpLiteral):
|
||||
loc = op.get(None)
|
||||
labels['label_{:04x}'.format(loc)] = loc
|
||||
elif isinstance(instruction, InstructionCall):
|
||||
if isinstance(instruction.args[0], OpLiteral):
|
||||
loc = instruction.args[0].get(None)
|
||||
labels['sub_{:04x}'.format(loc)] = loc
|
||||
else:
|
||||
SYN_PTR += 1
|
||||
# Read hints
|
||||
if args.hints:
|
||||
for hintfile in args.hints:
|
||||
with open(hintfile, 'r') as data:
|
||||
while True:
|
||||
line = data.readline()
|
||||
if line == '':
|
||||
break
|
||||
if line.startswith('jmp '):
|
||||
loc = int(line.split()[1], 16)
|
||||
labels['label_{:04x}'.format(loc)] = loc
|
||||
elif line.startswith('call '):
|
||||
loc = int(line.split()[1], 16)
|
||||
labels['sub_{:04x}'.format(loc)] = loc
|
||||
elif line.startswith('ren '):
|
||||
old_label = line.split()[1]
|
||||
new_label = line.split()[2]
|
||||
labels[new_label] = labels[old_label]
|
||||
del labels[old_label]
|
||||
elif line.startswith('cmb '):
|
||||
loc = int(line.split()[1], 16)
|
||||
comment = line[line.index(' ', line.index(' ') + 1) + 1:].strip()
|
||||
if loc not in comments_before:
|
||||
comments_before[loc] = []
|
||||
comments_before[loc].append(comment)
|
||||
else:
|
||||
raise Exception('Invalid line in hint file: {}'.format(line))
|
||||
|
||||
def escape_char(char):
|
||||
return char.encode('unicode_escape').decode('utf-8').replace('"', '\\"')
|
||||
|
||||
@ -35,6 +85,30 @@ MODE_DAT = False #False, 1 (data), 2 (text)
|
||||
SYN_PTR = 0
|
||||
|
||||
while SYN_PTR < len(SYN_MEM):
|
||||
if SYN_PTR in comments_before:
|
||||
if MODE_OUT:
|
||||
print('"')
|
||||
MODE_OUT = False
|
||||
if MODE_DAT == 1:
|
||||
print()
|
||||
MODE_DAT = False
|
||||
if MODE_DAT == 2:
|
||||
print('"')
|
||||
MODE_DAT = False
|
||||
for comment in comments_before[SYN_PTR]:
|
||||
print('; {}'.format(comment))
|
||||
if any(v == SYN_PTR for k, v in labels.items()):
|
||||
if MODE_OUT:
|
||||
print('"')
|
||||
MODE_OUT = False
|
||||
if MODE_DAT == 1:
|
||||
print()
|
||||
MODE_DAT = False
|
||||
if MODE_DAT == 2:
|
||||
print('"')
|
||||
MODE_DAT = False
|
||||
print('${}:'.format(next(k for k, v in labels.items() if v == SYN_PTR)))
|
||||
|
||||
word = SYN_MEM[SYN_PTR]
|
||||
|
||||
if MODE_OUT and word != 19:
|
||||
@ -72,7 +146,7 @@ while SYN_PTR < len(SYN_MEM):
|
||||
SYN_PTR += 1
|
||||
else:
|
||||
# Instruction
|
||||
instruction, SYN_PTR = Instruction.next_instruction(SYN_MEM, SYN_PTR)
|
||||
instruction, next_SYN_PTR = Instruction.next_instruction(SYN_MEM, SYN_PTR)
|
||||
# Special cases
|
||||
if isinstance(instruction, InstructionOut):
|
||||
if isinstance(instruction.args[0], OpLiteral):
|
||||
@ -89,5 +163,20 @@ while SYN_PTR < len(SYN_MEM):
|
||||
print('"')
|
||||
MODE_OUT = False
|
||||
print('{:04x}: {}'.format(SYN_PTR, instruction.describe()))
|
||||
elif isinstance(instruction, InstructionJmp) or isinstance(instruction, InstructionJt) or isinstance(instruction, InstructionJf) or isinstance(instruction, InstructionCall):
|
||||
if isinstance(instruction, InstructionJmp) or isinstance(instruction, InstructionCall):
|
||||
op = instruction.args[0]
|
||||
else:
|
||||
op = instruction.args[1]
|
||||
if isinstance(op, OpLiteral):
|
||||
loc = op.get(None)
|
||||
if any(v == loc for k, v in labels.items()):
|
||||
label = next(k for k, v in labels.items() if v == loc)
|
||||
print('{:04x}: {: <4} ${}'.format(SYN_PTR, instruction.name, label))
|
||||
else:
|
||||
print('{:04x}: {}'.format(SYN_PTR, instruction.describe()))
|
||||
else:
|
||||
print('{:04x}: {}'.format(SYN_PTR, instruction.describe()))
|
||||
else:
|
||||
print('{:04x}: {}'.format(SYN_PTR, instruction.describe()))
|
||||
SYN_PTR = next_SYN_PTR
|
||||
|
6
disasm_hints/annotations.txt
Normal file
6
disasm_hints/annotations.txt
Normal file
@ -0,0 +1,6 @@
|
||||
jmp 0000
|
||||
ren label_0000 start
|
||||
jmp 0110
|
||||
ren label_0110 self_test
|
||||
cmb 0140 Test jmp
|
||||
ren label_015b self_test_jmp1
|
95
disasm_hints/jmpcall.txt
Normal file
95
disasm_hints/jmpcall.txt
Normal file
@ -0,0 +1,95 @@
|
||||
call 0505
|
||||
call 0507
|
||||
call 05b2
|
||||
call 05ee
|
||||
call 05f8
|
||||
call 05fb
|
||||
call 0607
|
||||
call 0623
|
||||
call 0634
|
||||
call 0645
|
||||
call 0653
|
||||
call 0670
|
||||
call 0683
|
||||
call 06bb
|
||||
call 06e7
|
||||
call 0731
|
||||
call 07d1
|
||||
call 084d
|
||||
call 0865
|
||||
call 086e
|
||||
call 0882
|
||||
call 08c8
|
||||
call 08e9
|
||||
call 0b94
|
||||
call 0cad
|
||||
call 0d48
|
||||
call 0df0
|
||||
call 0e48
|
||||
call 0e8f
|
||||
call 0e9e
|
||||
call 0ec0
|
||||
call 0eca
|
||||
call 0ede
|
||||
call 0f35
|
||||
call 0f98
|
||||
call 0fa9
|
||||
call 0fcd
|
||||
call 0fde
|
||||
call 1000
|
||||
call 1011
|
||||
call 1022
|
||||
call 1033
|
||||
call 1044
|
||||
call 107a
|
||||
call 10b7
|
||||
call 1135
|
||||
call 11a3
|
||||
call 11b5
|
||||
call 1203
|
||||
call 1252
|
||||
call 1270
|
||||
call 12bf
|
||||
call 1315
|
||||
call 1371
|
||||
call 14f0
|
||||
call 1501
|
||||
call 1512
|
||||
call 1523
|
||||
call 1534
|
||||
call 1545
|
||||
call 1659
|
||||
call 16b6
|
||||
call 16bf
|
||||
call 16d6
|
||||
call 16f4
|
||||
call 1705
|
||||
call 1721
|
||||
call 174c
|
||||
call 1766
|
||||
jmp 015b
|
||||
jmp 0166
|
||||
jmp 01e4
|
||||
jmp 02c4
|
||||
jmp 02db
|
||||
jmp 034d
|
||||
jmp 03e8
|
||||
jmp 061e
|
||||
jmp 06b2
|
||||
jmp 06fb
|
||||
jmp 07e3
|
||||
jmp 07ff
|
||||
jmp 0833
|
||||
jmp 08bc
|
||||
jmp 08cc
|
||||
jmp 08f8
|
||||
jmp 0aae
|
||||
jmp 0b86
|
||||
jmp 0c79
|
||||
jmp 0cfe
|
||||
jmp 0d99
|
||||
jmp 0e43
|
||||
jmp 112e
|
||||
jmp 1312
|
||||
jmp 1652
|
||||
jmp 1747
|
Reference in New Issue
Block a user