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
|
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
|
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
|
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
|
#!/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