def test(): start = Label() end = Label() prog = Program( push(ebp), mov(ebp, esp), mov(ebx, ebp.addr + 8), mov(eax, 1), start, cmp(ebx, 1), jl(end), mul(ebx), dec(ebx), jmp(start), end, pop(ebp), ret(), ) fun = prog.compile(restype=c_int, argtypes=[c_int]) for i in range( 13 ): #factorial of 12 is the maximum integer fitting a 32 bit register assert fun(i) == factorial(i)
def test(): label = Label('foo') prog = Program( mov(eax, 0), label, inc(eax), cmp(eax, 100), jl(label), ret(), ) fun = prog.compile(c_int) assert fun() == 100
def test(): prog = Program( push(ebp), mov(ebp, esp), mov(eax, ebp.addr+8), cmp(eax, 100), pushfd(), pop(eax), pop(ebp), ret(), ) fun = prog.compile(c_int, [c_int]) assert fun(99) & CF assert fun(100) & ZF assert not (fun(101) & CF or fun(101) & ZF)
def test(): prog = Program( push(ebp), mov(ebp, esp), mov(eax, ebp.addr + 8), cmp(eax, 100), pushfd(), pop(eax), pop(ebp), ret(), ) fun = prog.compile(c_int, [c_int]) assert fun(99) & CF assert fun(100) & ZF assert not (fun(101) & CF or fun(101) & ZF)
def test(): loop = Label() prog = Program( push(ebp), mov(ebp, esp), mov(eax, ebp.addr + 8), mov(ebx, ebp.addr + 12), mov(ecx, ebp.addr + 16), mov(edx, ebp.addr + 20), loop, fld(ebx.addr), fmul(ecx.addr), fstp(edx.addr), add(ebx, 4), add(ecx, 4), add(edx, 4), dec(eax), cmp(eax, 0), jg(loop), pop(ebp), ret(), ) fun = prog.compile(argtypes=[ c_int, POINTER(c_float), POINTER(c_float), POINTER(c_float), ]) size = 1000 a = (c_float * size)() b = (c_float * size)() c = (c_float * size)() a[:] = range(0, size) b[:] = range(size, size * 2) c[:] = [0] * size fun(size, a, b, c) #weirdly off by 1 for higher result numbers for i in range(size): assert c[i] == a[i] * b[i]
def test(): loop = Label() prog = Program( push(ebp), mov(ebp, esp), mov(eax, ebp.addr+8), mov(ebx, ebp.addr+12), mov(ecx, ebp.addr+16), mov(edx, ebp.addr+20), loop, fld(ebx.addr), fmul(ecx.addr), fstp(edx.addr), add(ebx, 4), add(ecx, 4), add(edx, 4), dec(eax), cmp(eax, 0), jg(loop), pop(ebp), ret(), ) fun = prog.compile(argtypes=[ c_int, POINTER(c_float), POINTER(c_float), POINTER(c_float), ]) size = 1000 a = (c_float*size)() b = (c_float*size)() c = (c_float*size)() a[:] = range(0, size) b[:] = range(size, size*2) c[:] = [0] * size fun(size, a, b, c) #weirdly off by 1 for higher result numbers for i in range(size): assert c[i] == a[i] * b[i]
def test(): start = Label() end = Label() prog = Program( push(ebp), mov(ebp, esp), mov(ebx, ebp.addr+8), mov(eax, 1), start, cmp(ebx, 1), jl(end), mul(ebx), dec(ebx), jmp(start), end, pop(ebp), ret(), ) fun = prog.compile(restype=c_int, argtypes=[c_int]) for i in range(13): #factorial of 12 is the maximum integer fitting a 32 bit register assert fun(i) == factorial(i)
def compile(): outer_loop = Label() inner_loop = Label() distance_condition = Label() distance_else = Label() min_condition = Label() size_condition = Label() prog = Program( push(ebp), mov(ebp, esp), mov(eax, ebp.addr + 8), #size cmp(eax, 2), jl(size_condition), mov(ecx, ebp.addr + 12), #array pointer fld(ebp.addr + 16), #force factor fld(ebp.addr + 20), #minimum distance fld(ebp.addr + 24), #maximum distance sub(eax, 1), mov(ebx, 4 * 4), mul(ebx), add(ecx, eax), mov(eax, ebp.addr + 12), #array pointer outer_loop, mov(ebx, eax), add(ebx, 4 * 4), inner_loop, # x vector fld(eax.addr + 0 * 4), fsub(ebx.addr + 0 * 4), # y vector fld(eax.addr + 1 * 4), fsub(ebx.addr + 1 * 4), # distance fld(st(1)), fmul(st(0), st(0)), fld(st(1)), fmul(st(0), st(0)), faddp(), fsqrt(), #make sure the distance is bigger then 10 fcomi(st(4)), fcmovb(st(4)), #only calculate if the distance is less then 200 fcomi(st(3)), ja(distance_condition), #cube distance fld(st(0)), fmul(st(1), st(0)), fmulp(), #compute force vector fdiv(st(2), st(0)), fdivp(), fld(st(4)), fmul(st(2), st(0)), fmulp(), #accumulate y component fld(st(0)), fadd(eax.addr + 3 * 4), fstp(eax.addr + 3 * 4), fsubr(ebx.addr + 3 * 4), fstp(ebx.addr + 3 * 4), #accumulate x component fld(st(0)), fadd(eax.addr + 2 * 4), fstp(eax.addr + 2 * 4), fsubr(ebx.addr + 2 * 4), fstp(ebx.addr + 2 * 4), jmp(distance_else), distance_condition, fstp(st(0)), fstp(st(0)), fstp(st(0)), distance_else, add(ebx, 4 * 4), cmp(ebx, ecx), jbe(inner_loop), add(eax, 4 * 4), cmp(eax, ecx), jb(outer_loop), #restore the fpu fstp(st(0)), fstp(st(0)), fstp(st(0)), size_condition, pop(ebp), ret(), ) fun = prog.compile(argtypes=[ c_int, POINTER(c_float), c_float, c_float, c_float, ]) return fun
def compile(): outer_loop = Label() inner_loop = Label() distance_condition = Label() distance_else = Label() min_condition = Label() size_condition = Label() prog = Program( push(ebp), mov(ebp, esp), mov(eax, ebp.addr+8), #size cmp(eax, 2), jl(size_condition), mov(ecx, ebp.addr+12), #array pointer fld(ebp.addr+16), #force factor fld(ebp.addr+20), #minimum distance fld(ebp.addr+24), #maximum distance sub(eax, 1), mov(ebx, 4*4), mul(ebx), add(ecx, eax), mov(eax, ebp.addr+12), #array pointer outer_loop, mov(ebx, eax), add(ebx, 4*4), inner_loop, # x vector fld(eax.addr+0*4), fsub(ebx.addr+0*4), # y vector fld(eax.addr+1*4), fsub(ebx.addr+1*4), # distance fld(st(1)), fmul(st(0), st(0)), fld(st(1)), fmul(st(0), st(0)), faddp(), fsqrt(), #make sure the distance is bigger then 10 fcomi(st(4)), fcmovb(st(4)), #only calculate if the distance is less then 200 fcomi(st(3)), ja(distance_condition), #cube distance fld(st(0)), fmul(st(1), st(0)), fmulp(), #compute force vector fdiv(st(2), st(0)), fdivp(), fld(st(4)), fmul(st(2), st(0)), fmulp(), #accumulate y component fld(st(0)), fadd(eax.addr+3*4), fstp(eax.addr+3*4), fsubr(ebx.addr+3*4), fstp(ebx.addr+3*4), #accumulate x component fld(st(0)), fadd(eax.addr+2*4), fstp(eax.addr+2*4), fsubr(ebx.addr+2*4), fstp(ebx.addr+2*4), jmp(distance_else), distance_condition, fstp(st(0)), fstp(st(0)), fstp(st(0)), distance_else, add(ebx, 4*4), cmp(ebx, ecx), jbe(inner_loop), add(eax, 4*4), cmp(eax, ecx), jb(outer_loop), #restore the fpu fstp(st(0)), fstp(st(0)), fstp(st(0)), size_condition, pop(ebp), ret(), ) fun = prog.compile(argtypes=[ c_int, POINTER(c_float), c_float, c_float, c_float, ]) return fun
from ctypes import POINTER, c_long from pyasm import Program from pyasm.base import Label from pyasm.instructions import mov, mul, dec, cmp, jg, ret from pyasm.registers import rax, rdi def factorial(value): accum = 1 while value > 1: accum *= value value -= 1 return accum if __name__ == '__main__': loop = Label() prog = Program( mov(rax, 1), loop, mul(rax, rdi), dec(rdi), cmp(rax, 1), ja(loop), ret() ) fun = prog.compile(restype=c_long, argtypes=[c_long]) for i in xrange(20): assert fun(i) == factorial(i)