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 = argparse.ArgumentParser()
|
||||||
parser.add_argument('file', help='.bin file containing the initial memory dump')
|
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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
with open(args.file, 'rb') as data:
|
with open(args.file, 'rb') as data:
|
||||||
SYN_MEM = memory_from_file(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):
|
def escape_char(char):
|
||||||
return char.encode('unicode_escape').decode('utf-8').replace('"', '\\"')
|
return char.encode('unicode_escape').decode('utf-8').replace('"', '\\"')
|
||||||
|
|
||||||
@ -35,6 +85,30 @@ MODE_DAT = False #False, 1 (data), 2 (text)
|
|||||||
SYN_PTR = 0
|
SYN_PTR = 0
|
||||||
|
|
||||||
while SYN_PTR < len(SYN_MEM):
|
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]
|
word = SYN_MEM[SYN_PTR]
|
||||||
|
|
||||||
if MODE_OUT and word != 19:
|
if MODE_OUT and word != 19:
|
||||||
@ -72,7 +146,7 @@ while SYN_PTR < len(SYN_MEM):
|
|||||||
SYN_PTR += 1
|
SYN_PTR += 1
|
||||||
else:
|
else:
|
||||||
# Instruction
|
# Instruction
|
||||||
instruction, SYN_PTR = Instruction.next_instruction(SYN_MEM, SYN_PTR)
|
instruction, next_SYN_PTR = Instruction.next_instruction(SYN_MEM, SYN_PTR)
|
||||||
# Special cases
|
# Special cases
|
||||||
if isinstance(instruction, InstructionOut):
|
if isinstance(instruction, InstructionOut):
|
||||||
if isinstance(instruction.args[0], OpLiteral):
|
if isinstance(instruction.args[0], OpLiteral):
|
||||||
@ -89,5 +163,20 @@ while SYN_PTR < len(SYN_MEM):
|
|||||||
print('"')
|
print('"')
|
||||||
MODE_OUT = False
|
MODE_OUT = False
|
||||||
print('{:04x}: {}'.format(SYN_PTR, instruction.describe()))
|
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:
|
else:
|
||||||
print('{:04x}: {}'.format(SYN_PTR, instruction.describe()))
|
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