Created
April 7, 2016 09:26
-
-
Save alanduan/238cc21ab52b72b262d7be9c50045d68 to your computer and use it in GitHub Desktop.
8086 emulator utils
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
from itertools import product | |
# bx(n) generates all bit strings with length n | |
bx = lambda x: (('{:0%db}' % x).format(i) for i in xrange(2**x)) | |
# bit8s(s) iterates every 8-bit strings from s | |
bit8s = lambda x: (x[i:i+8] for i in range(0, len(x), 8)) | |
# convert bit string into integer | |
ints = lambda x: (int(i, 2) for i in x) | |
# convert integer into byte so it could be written to files | |
chars = lambda x: (chr(i) for i in x) | |
# padding instruction into 6 bytes (max of 8086 ins size) | |
# then write it into a temporary file which disasm by nasm | |
# read the first instruction disasm by nasm | |
# TODO: real instruction size could be useful | |
def disasm(ins): | |
i = ins + '0'*(48-len(ins)) if len(ins) < 48 else ins | |
with open('temp.txt', 'wb') as f: | |
f.write(''.join(chars(ints(bit8s(i))))) | |
os.system('ndisasm temp.txt | head -1') | |
key_size_map = dict(dw=2, mod=2, reg=3, rm=3, data8=8, data_lo=8, data_hi=8) | |
# generate every possible implementation of given instruction pattern | |
def pattern_imps(p): | |
keys = re.findall(r'\{(.*?)\}', p) | |
sizes = (key_size_map[i] for i in keys) | |
return (pattern.format(**dict(zip(keys, i))) | |
for i in product(*(bx(i) for i in sizes))) | |
pattern = '000000{dw}{mod}{reg}{rm}' | |
pattern = '00000101{data_lo}{data_hi}' | |
pattern = '00000100{data8}' | |
for i in pattern_imps(pattern): | |
print i | |
disasm(i) | |
import sys; sys.exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment