cheery / g386
A two-pass assembler for i386. Implements a subset of instruction encoders and implements more if benchmarks promote. Produces linux ELF binaries but isn't limited into them. Straightforward design.
| commit 24: | 1020f2548a1c |
| parent 23: | e6566a632fab |
| branch: | default |
save to memory -mechanism
Changed (Δ1.2 KB):
raw changeset »
g386/mem.py (46 lines added, 0 lines removed)
1 |
# -*- coding: utf-8 -*- |
|
2 |
""" |
|
3 |
mem |
|
4 |
~~~ |
|
5 |
||
6 |
:copyright: 2010 by Henri Tuhola <henri.tuhola@gmail.com> |
|
7 |
||
8 |
This works only on 32bit python. |
|
9 |
""" |
|
10 |
from ctypes import CDLL, memmove, cast |
|
11 |
from core import pass0, pass1 |
|
12 |
from mmap import MAP_ANONYMOUS, MAP_PRIVATE, PROT_EXEC, PROT_READ, PROT_WRITE |
|
13 |
||
14 |
libc = CDLL('libc.so.6') |
|
15 |
||
16 |
PROT_ALL = PROT_EXEC | PROT_READ | PROT_WRITE |
|
17 |
MAP_PROGRAM = MAP_ANONYMOUS | MAP_PRIVATE |
|
18 |
||
19 |
class ProgramInMemory(object): |
|
20 |
def __init__(self, assembly, functype): |
|
21 |
size = pass0([assembly], 0) |
|
22 |
address = libc.mmap(None, size, PROT_ALL, MAP_PROGRAM, 0, 0) |
|
23 |
pass0([assembly], address) |
|
24 |
memmove(address, pass1([assembly]), size) |
|
25 |
self.address = address |
|
26 |
self.size = size |
|
27 |
self.function = cast(address, functype) |
|
28 |
||
29 |
def discard(self): |
|
30 |
libc.munmap(self.address, self.size) |
|
31 |
||
32 |
def __call__(self, *args): |
|
33 |
return self.function(*args) |
|
34 |
||
35 |
if __name__ == '__main__': |
|
36 |
from g386 import X86, Assembly, Deref, r0,r1,r2,r3,r4,r5,r6,r7 |
|
37 |
from ctypes import CFUNCTYPE, c_int |
|
38 |
||
39 |
regs = [r0,r1,r2,r3,r6,r7] |
|
40 |
||
41 |
x = little_function = X86(regs) |
|
42 |
x.move(r0, x.add(Deref(r4, 4), 50)) |
|
43 |
x.ret() |
|
44 |
||
45 |
mem = ProgramInMemory(little_function, CFUNCTYPE(c_int, c_int)) |
|
46 |
print mem(500) |
