Add disassembler script and link

This commit is contained in:
Jay 2020-08-26 12:07:14 -07:00
parent 2963d46fcb
commit b7a8a80350
2 changed files with 171 additions and 1 deletions

View File

@ -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

170
2020/gctf/sprint/disassemble.py Executable file
View File

@ -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])