-
Notifications
You must be signed in to change notification settings - Fork 2
/
assembler.py
executable file
·64 lines (57 loc) · 1.72 KB
/
assembler.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
#!/usr/bin/python
import sys
from pwn import *
insts = {'DUP': '$', 'POP': '%', 'AND': '&', 'MUL': '*', 'ADD': '+', 'WRITE':
',', 'MINUS': '-', 'WRITED': '.', 'DIV': '/', 'STORE':':', 'FETCH':';',
'EQ':'=', 'GT':'>', 'ROT': '@', 'SWAP': '\\', 'NEG': '_', 'OR': '|',
'NOT': '~'}
def error(line, linenum, msg):
print("ERROR on line %d: %s:\n %s" % (linenum, msg, line))
def to_dwords(s):
s += '\0' * (4 - len(s) % 4)
nums = []
for i in range(0, len(s), 4):
nums += [u32(s[i:i+4])]
return nums
def assemble(fname):
linenum = 0
f = open(fname, "r")
code = ''
asmmode = False
asmcode = ''
for l in f:
linenum += 1
ll = l.split('#')[0].strip().upper()
if asmmode:
if ll == 'ENDASM':
nums = to_dwords(asm(asmcode, arch='x86_64'))
code += '`'.join(map(str, nums)) + '`'
code += insts['POP'] * len(nums)
asmmode = False
else:
asmcode += l.split('#')[0].strip() + '\n'
continue
if ll == '':
continue
elif ll[0] in '0123456789':
try:
code += str(int(ll)) + '`'
except:
error(l, linenum, "Invalid number")
elif ll == 'ASM':
asmmode = True
else:
if ll in insts:
code += insts[ll]
else:
error(l, linenum, "Invalid instruction")
if asmmode:
error('', linenum, "Expected 'ENDASM'")
return code
def main():
if len(sys.argv) != 2:
print("Usage: %s <file>" % sys.argv[0])
exit(1)
print(assemble(sys.argv[1]))
if __name__ == '__main__':
main()