Пример #1
0
def main():
    lexout = True
    #asmout = False
    options = ""
    filearg = ""

    # print information if there are no arguments
    if len(sys.argv) == 1:
        print("%sProvide a file.\n" % cBR)
        information()

    # get arguments
    else:
        for arg in sys.argv:
            if re.match(r"-", arg):
                options = arg
            else:
                filearg = arg

    # "parse" options
    if re.search(r"h", options):
        information()
    if re.search(r"l", options):
        lexout = True
    #if re.search(r"a", options):
    #    asmout = True
    if filearg == "":
        information()

    # open
    try:
        print("%sOpening %s[%s]" % (cBW, cW, sys.argv[1]))
        with open(sys.argv[1], "r") as f:
            print("\t.")
            file = f.read()
    except FileNotFoundError:
        print("%s\tERROR %sfile not found.%s" % (cBR, cR, cW))
        exit()

    # lex
    types = []
    values = []
    lines = []
    print("%sLexing%s" % (cBW, cW))
    types, values, lines = lexfile(file, lexout)

    # assemble
    print("%sAssembling%s" % (cBW, cW))
    assemble(types, values, lines)
Пример #2
0
def t_asm(ass, ex, exact=True, check_dis=True):
    ass = ass.strip()
    bc = asm.assemble(ass)
    dis = disasm.disassemble(bc)
    dis = unformat(dis)
    if check_dis and dis != ass:
        print(ass)
        print(dis)
        assert (dis == ass)
    fname = "tmp.tpc"
    system_rm(fname)
    system_rm(TMP)
    save(fname, bc)
    cmd = VM + fname + " > " + TMP
    system(cmd)
    res = load("tmp.txt").strip()
    if exact:
        if ex != res:
            print(ass)
            print(ex)
            print(res)
            assert (ex == res)
    else:
        if ex not in res:
            print(ass)
            print(ex)
            print(res)
            assert (ex in res)
Пример #3
0
def t_asm(ass, ex, exact=True,check_dis=True):
    ass = ass.strip()
    bc = asm.assemble(ass)
    dis = disasm.disassemble(bc)
    dis = unformat(dis)
    if check_dis and dis != ass:
        print (ass)
        print (dis)
        assert(dis == ass)
    fname = "tmp.tpc"
    system_rm(fname)
    system_rm(TMP)
    save(fname,bc)
    cmd = VM + fname + " > " + TMP
    system(cmd)
    res = load("tmp.txt").strip()
    if exact:
        if ex != res:
            print (ass)
            print (ex)
            print (res)
            assert(ex == res)
    else:
        if ex not in res:
            print (ass)
            print (ex)
            print (res)
            assert(ex in res)
Пример #4
0
 def test_data_instructions(self):
     prefix = 'data'
     files = list(glob.glob('asm/{}*.asm'.format(prefix)))
     self.assertNotEqual(files, [])
     for fname in files:
         with self.subTest(file=fname):
             with open(fname, 'r') as f:
                 code = asm.assemble(f)
             with open(fname[:-3] + 'hex', 'r') as outf:
                 code_hex = []
                 for line in outf:
                     code_hex.extend(line.strip().split(' '))
             for i, b in enumerate(code):
                 self.assertEqual(b, int(code_hex[i], 16))
             print('{} OK'.format(fname))
Пример #5
0
        continue
    # Split to words
    infile[x] = infile[x].split()
    # Handle Label
    if infile[x][0][-1] == ":":
        labels[infile[x][0][:-1]] = count
        infile[x].pop(0)
        # If left with an empty string after removal, pop it and come again, else increase count because you have a valid line
        if len(infile[x]) == 0:
            infile.pop(x)
            continue
    count += 1
    x += 1

x = 0
# Civilize the instr, remove labelish anarchy
while x < len(infile):
    if (infile[x][-1][0] != 'R'
            or not infile[x][-1][1].isdigit()) and infile[x][-1][0] != '#':
        infile[x][-1] = "#" + str(labels[infile[x][-1]] - 1)
    infile[x] = " ".join(infile[x])
    # Translate the string to machine code
    infile[x] = asm.assemble(infile[x]) + ";"
    x += 1

count = 0
for x in infile:
    num = hex(count)[2:].upper()
    print 'i' + (2 - len(num)) * '0' + num + " = " + x
    count += 1
Пример #6
0
def fastcall(addr, ret_t, *arg_ts):
    """In-process functions with MS __fastcall calling convention.

    First two arguments passed in ECX and EDX, left-to-right.
    The rest are pushed on stack right-to-left. Callee cleans up stack.
    Return in EAX. (EAX,ECX,EDX are thus available for use.)
    """
    # assemble an asm wrapper around the function
    # this gets done just once, at module load time, by the decorator
    #
    # since parameters are unknown, the machine code is parametrized via
    # string.format(*args), to be swapped in on function call
    #
    # alternatively, could wrap with an stdcall... but eh, this is more flexible
    s = 'push ebx;'
    junk = 0 # how many bytes to clean off the stack
    # first two arguments in registers
    if len(arg_ts)>0: s += 'mov ecx {0};'
    if len(arg_ts)>1: s += 'mov edx {1};'
    # variable arguments on the stack
    vargs = len(arg_ts)-2
    if vargs>0:
        junk += 4*vargs # args are DWORDs
        for n in range(2, 2+vargs):
            s += 'mov eax {%d}; push eax;' % (n,)
    # function call and cleanup
    s +='''
        mov ebx $func_addr
        call ebx
        pop ebx
        retn $stack_junk
        '''
    asm_code = s
    machine_code = asm.assemble(asm_code,
                                func_addr=asm.DWORD(addr),
                                stack_junk=asm.WORD(junk))
    
    def cfun(*args):
        # pack arguments into 4-byte form suitable for stack
        # TODO sign?
        # TODO proper handling of arg_ts ctypes
        conv_args = ()
        for arg in args:
                conv_args+=(asm.DWORD(arg),)
        args = conv_args
        # insert particular arguments into preassembled machine code
        code = machine_code.format(*args)
        # execute
        ret = c_uint(asm.call(code)())
        # hammer the retval into a correct shape via pointer typecast
        return cast(pointer(ret), POINTER(ret_t)).contents
    
    def wrap1(f):
        # this part is just like it was for stdcall and cdecl
        def wrap2(*args):
            gen = f(*args)
            args = gen.send(None) # let coroutine work with args if it wants to
            ret = cfun(*args) # execute C function, hope it doesn't failboat
            ret = gen.send(ret) # let coroutine work with retval if it wants to
            return ret
        return wrap2
    return wrap1
Пример #7
0
 def assemble_input(self, *args):
     assembly = self.text_box.get(0.0, END)
     program = assemble(assembly)
     with tempfile.TemporaryFile() as f:
         f.write(program)
Пример #8
0
def test_assemble_example():
    with open('example.s') as f:
        example = f.read()

    assert assemble(example) == prog
Пример #9
0
def test_assemble_disasseble_cycle():
    code = assemble(asm)

    assert assemble(disassemble(code)) == code
Пример #10
0
def test_assemble_disassembled():
    assert assemble(asm) == prog