backtracking and labeling for the disassembler

This commit is contained in:
Bryan Bishop 2012-06-10 18:26:18 -05:00
parent 10a5a6518d
commit cd60a1f0e4

View File

@ -163,14 +163,18 @@ class Asm:
current_byte_number = len(asm_commands.keys()) current_byte_number = len(asm_commands.keys())
# setup this next/upcoming command # setup this next/upcoming command
asm_command = { if offset in asm_commands.keys():
"address": offset, asm_command = asm_commands[offset]
else:
asm_command = {}
asm_command["address"] = offset
if not "references" in asm_command.keys():
# This counts how many times relative jumps reference this # This counts how many times relative jumps reference this
# byte. This is used to determine whether or not to print out a # byte. This is used to determine whether or not to print out a
# label later. # label later.
"references": 0, asm_command["references"] = 0
}
# some commands have two opcodes # some commands have two opcodes
next_byte = ord(rom[offset+1]) next_byte = ord(rom[offset+1])
@ -199,6 +203,10 @@ class Asm:
if "x" in opstr: if "x" in opstr:
for x in range(0, opstr.count("x")): for x in range(0, opstr.count("x")):
insertion = ord(rom[offset + 1]) insertion = ord(rom[offset + 1])
# Certain opcodes will have a local relative jump label
# here instead of a raw hex value, but this is
# controlled through asm output.
insertion = "$" + hex(insertion)[2:] insertion = "$" + hex(insertion)[2:]
opstr = opstr[:opstr.find("x")].lower() + insertion + opstr[opstr.find("x")+1:].lower() opstr = opstr[:opstr.find("x")].lower() + insertion + opstr[opstr.find("x")+1:].lower()
@ -214,6 +222,8 @@ class Asm:
number = byte1 number = byte1
number += byte2 << 8; number += byte2 << 8;
# In most cases, you can use a label here. Labels will
# be shown during asm output.
insertion = "$%.4x" % (number) insertion = "$%.4x" % (number)
opstr = opstr[:opstr.find("?")].lower() + insertion + opstr[opstr.find("?")+1:].lower() opstr = opstr[:opstr.find("?")].lower() + insertion + opstr[opstr.find("?")+1:].lower()
@ -227,19 +237,35 @@ class Asm:
# generate a label for the byte we're jumping to # generate a label for the byte we're jumping to
target_address = offset + 2 + c_int8(ord(rom[offset + 1])).value target_address = offset + 2 + c_int8(ord(rom[offset + 1])).value
if target_address in byte_labels.keys(): if target_address in asm_commands.keys():
byte_labels[target_address]["usage"] = 1 + byte_labels[target_address]["usage"] asm_commands[target_address]["references"] += 1
line_label2 = byte_labels[target_address]["name"] remote_label = "asm_" + hex(target_address)
asm_commands[target_address]["current_label"] = remote_label
asm_command["remote_label"] = remote_label
asm_command["use_remote_label"] = True
else: else:
line_label2 = asm_label(target_address) remote_label = "asm_" + hex(target_address)
byte_labels[target_address] = {}
byte_labels[target_address]["name"] = line_label2
byte_labels[target_address]["usage"] = 1
byte_labels[target_address]["definition"] = False
insertion = line_label2.lower() # This remote address might not be part of this
include_comment = True # function.
asm_commands[target_address] = {
"references": 1,
"current_label": remote_label,
}
# Also, target_address can be negative (before the
# start_address that the user originally requested),
# and it shouldn't be shown on asm output because the
# intermediate bytes (between a negative target_address
# and start_address) won't be disassembled.
# Don't know yet if this remote address is part of this
# function or not. When the remote address is not part
# of this function, the label name should not be used,
# because that label will not be disassembled in the
# output, until the user asks it to.
asm_command["use_remote_label"] = "unknown"
asm_command["remote_label"] = remote_label
elif current_byte == 0x3e: elif current_byte == 0x3e:
last_a_address = ord(rom[offset + 1]) last_a_address = ord(rom[offset + 1])
@ -282,7 +308,7 @@ class Asm:
asm_command["value"] = current_byte asm_command["value"] = current_byte
# save this new command in the list # save this new command in the list
asm_commands[current_byte_number] = asm_command asm_commands[asm_command["address"]] = asm_command
def __str__(self): def __str__(self):
""" ASM pretty printer. """ ASM pretty printer.