Add disassembler script and link
This commit is contained in:
parent
2963d46fcb
commit
b7a8a80350
|
@ -276,7 +276,7 @@ Now we write a python script to parse each of the types of
|
|||
instructions we've seen above, and translate them to human-readable
|
||||
form. We can also check if some of the assumptions we've made hold
|
||||
and print an error message if they don't. The code below is
|
||||
abbreviated, you can find the full code [here](#).
|
||||
abbreviated, you can find the full code [here](disassemble.py).
|
||||
|
||||
#!/usr/bin/env python3
|
||||
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import fileinput
|
||||
import re
|
||||
|
||||
literalMove = re.compile(r"^%1\$(\d*)s%3\$hn%1\$(\d*)s%1\$(\d*)s%(\d*)\$hn$")
|
||||
regMove = re.compile(r"^%1\$(\d*)s%3\$hn%1\$(\d*)s%1\$\*(\d*)\$s%(\d*)\$hn$")
|
||||
regAdd = re.compile(r"^%1\$(\d*)s%3\$hn%1\$(\d*)s%1\$\*(\d*)\$s%1\$\*(\d*)\$s%(\d*)\$hn$")
|
||||
regLiteralAdd = re.compile(r"^%1\$(\d*)s%3\$hn%1\$(\d*)s%1\$\*(\d*)\$s%1\$(\d*)s%(\d*)\$hn$")
|
||||
literalRegAdd = re.compile(r"^%1\$(\d*)s%3\$hn%1\$(\d*)s%1\$(\d*)s%1\$\*(\d*)\$s%(\d*)\$hn$")
|
||||
jump = re.compile(r"^%1\$(\d*)s%3\$hn$")
|
||||
condJump = re.compile(r"^%(\d*)\$c%1\$(\d*)s%2\$c%4\$s%1\$(\d*)s%3\$hn$")
|
||||
|
||||
# The address of the instruction being read
|
||||
addr = 0
|
||||
|
||||
|
||||
def showRegisterDest(regRef):
|
||||
if regRef == 6:
|
||||
regStr = "(%r1)"
|
||||
elif regRef >= 7 and regRef <= 23 and regRef % 2 == 1:
|
||||
regStr = "%r{}".format(regRef // 2 - 2)
|
||||
else:
|
||||
print("bad destination: {}".format(regRef))
|
||||
exit()
|
||||
return regStr
|
||||
|
||||
|
||||
def showRegisterSource(regRef):
|
||||
if regRef == 5:
|
||||
regStr = "(%r1)"
|
||||
elif regRef >= 6 and regRef <= 22 and regRef % 2 == 0:
|
||||
regStr = "%r{}".format(regRef // 2 - 2)
|
||||
else:
|
||||
print("bad source")
|
||||
exit()
|
||||
return regStr
|
||||
|
||||
|
||||
for line in fileinput.input():
|
||||
oldAddr = addr
|
||||
addr += len(line)
|
||||
m = literalMove.match(line)
|
||||
if m:
|
||||
nextAddr = int(m.group(1))
|
||||
filler = int(m.group(2))
|
||||
literal = int(m.group(3))
|
||||
regRef = int(m.group(4))
|
||||
|
||||
if addr != nextAddr:
|
||||
print("address is not the next instruction")
|
||||
exit()
|
||||
if nextAddr + filler != 0x10000:
|
||||
print("first two numbers do not add to 0x10000")
|
||||
exit()
|
||||
|
||||
dest = showRegisterDest(regRef)
|
||||
print("{:04x}: mov 0x{:x}, {}".format(oldAddr, literal, dest))
|
||||
continue
|
||||
|
||||
m = regMove.match(line)
|
||||
if m:
|
||||
nextAddr = int(m.group(1))
|
||||
filler = int(m.group(2))
|
||||
sourceRef = int(m.group(3))
|
||||
destRef = int(m.group(4))
|
||||
|
||||
if addr != nextAddr:
|
||||
print("address is not the next instruction")
|
||||
exit()
|
||||
if nextAddr + filler != 0x10000:
|
||||
print("first two numbers do not add to 0x10000")
|
||||
exit()
|
||||
|
||||
source = showRegisterSource(sourceRef)
|
||||
dest = showRegisterDest(destRef)
|
||||
print("{:04x}: mov {}, {}".format(oldAddr, source, dest))
|
||||
continue
|
||||
|
||||
m = regAdd.match(line)
|
||||
if m:
|
||||
nextAddr = int(m.group(1))
|
||||
filler = int(m.group(2))
|
||||
source1Ref = int(m.group(3))
|
||||
source2Ref = int(m.group(4))
|
||||
destRef = int(m.group(5))
|
||||
|
||||
if addr != nextAddr:
|
||||
print("address is not the next instruction")
|
||||
exit()
|
||||
if nextAddr + filler != 0x10000:
|
||||
print("first two numbers do not add to 0x10000")
|
||||
exit()
|
||||
|
||||
source1 = showRegisterSource(source1Ref)
|
||||
source2 = showRegisterSource(source2Ref)
|
||||
dest = showRegisterDest(destRef)
|
||||
print("{:04x}: add {}, {}, {}".format(oldAddr, source1, source2, dest))
|
||||
continue
|
||||
|
||||
m = regLiteralAdd.match(line)
|
||||
if m:
|
||||
nextAddr = int(m.group(1))
|
||||
filler = int(m.group(2))
|
||||
sourceRef = int(m.group(3))
|
||||
literal = int(m.group(4))
|
||||
destRef = int(m.group(5))
|
||||
|
||||
if addr != nextAddr:
|
||||
print("address is not the next instruction")
|
||||
exit()
|
||||
if nextAddr + filler != 0x10000:
|
||||
print("first two numbers do not add to 0x10000")
|
||||
exit()
|
||||
|
||||
source = showRegisterSource(sourceRef)
|
||||
dest = showRegisterDest(destRef)
|
||||
print("{:04x}: add {}, 0x{:x}, {}".format(oldAddr, source, literal, dest))
|
||||
continue
|
||||
|
||||
m = literalRegAdd.match(line)
|
||||
if m:
|
||||
nextAddr = int(m.group(1))
|
||||
filler = int(m.group(2))
|
||||
sourceRef = int(m.group(4))
|
||||
literal = int(m.group(3))
|
||||
destRef = int(m.group(5))
|
||||
|
||||
if addr != nextAddr:
|
||||
print("address is not the next instruction")
|
||||
exit()
|
||||
if nextAddr + filler != 0x10000:
|
||||
print("first two numbers do not add to 0x10000")
|
||||
exit()
|
||||
|
||||
source = showRegisterSource(sourceRef)
|
||||
dest = showRegisterDest(destRef)
|
||||
print("{:04x}: add {}, 0x{:x}, {}".format(oldAddr, source, literal, dest))
|
||||
continue
|
||||
|
||||
m = jump.match(line)
|
||||
if m:
|
||||
target = int(m.group(1))
|
||||
if target == 0xfffe:
|
||||
print("{:04x}: halt".format(oldAddr))
|
||||
else:
|
||||
print("{:04x}: jmp {:04x}".format(oldAddr, target))
|
||||
continue
|
||||
|
||||
m = condJump.match(line)
|
||||
if m:
|
||||
sourceRef = int(m.group(1))
|
||||
fill1 = int(m.group(2))
|
||||
fill2 = int(m.group(3))
|
||||
|
||||
source = showRegisterSource(sourceRef)
|
||||
|
||||
zeroTarget = (fill1 + fill2 + 2) % 0x10000
|
||||
nonzeroTarget = (fill1 * 2 + fill2 + 3) % 0x10000
|
||||
|
||||
if zeroTarget == addr:
|
||||
print("{:04x}: jnz {}, {:04x}".format(oldAddr, source, nonzeroTarget))
|
||||
elif nonzeroTarget == addr:
|
||||
print("{:04x}: jz {}, {:04x}".format(oldAddr, source, zeroTarget))
|
||||
else:
|
||||
print("neither jump target is the next instruction")
|
||||
exit()
|
||||
continue
|
||||
|
||||
print(line[:-1])
|
Loading…
Reference in New Issue