forked from jtauber/dcpu16py
-
Notifications
You must be signed in to change notification settings - Fork 5
/
disasm.py
executable file
·70 lines (55 loc) · 2.02 KB
/
disasm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/usr/bin/env python
import sys
INSTRUCTIONS = [None, "SET", "ADD", "SUB", "MUL", "DIV", "MOD", "SHL", "SHR", "AND", "BOR", "XOR", "IFE", "IFN", "IFG", "IFB"]
IDENTIFERS = ["A", "B", "C", "X", "Y", "Z", "I", "J", "POP", "PEEK", "PUSH", "SP", "PC", "O"]
class Disassembler:
def __init__(self, program):
self.program = program
self.offset = 0
def next_word(self):
w = self.program[self.offset]
self.offset += 1
return w
def format_operand(self, operand):
if operand < 0x08:
return "%s" % IDENTIFERS[operand]
elif operand < 0x10:
return "[%s]" % IDENTIFERS[operand % 0x08]
elif operand < 0x18:
return "[0x%02x + %s]" % (self.next_word(), IDENTIFERS[operand % 0x10])
elif operand < 0x1E:
return "%s" % IDENTIFERS[operand % 0x10]
elif operand == 0x1E:
return "[0x%02x]" % self.next_word()
elif operand == 0x1F:
return "0x%02x" % self.next_word()
else:
return "0x%02x" % (operand % 0x20)
def run(self):
while self.offset < len(self.program):
offset = self.offset
w = self.next_word()
operands, opcode = divmod(w, 16)
b, a = divmod(operands, 64)
if opcode == 0x00:
if a == 0x01:
first = "JSR"
else:
continue
else:
first = "%s %s" % (INSTRUCTIONS[opcode], self.format_operand(a))
print "%04x: %s, %s" % (offset, first, self.format_operand(b))
if __name__ == "__main__":
if len(sys.argv) == 2:
program = []
f = open(sys.argv[1])
while True:
hi = f.read(1)
if not hi:
break
lo = f.read(1)
program.append((ord(hi) << 8) + ord(lo))
d = Disassembler(program)
d.run()
else:
print "usage: ./disasm.py <object-file>"