Inline assembly in Python
Project description
il - inline assembly in Python 3
Examples
- Decorator API - simple
import il
import ctypes
@il.asm
def add_ints(rdi=ctypes.c_int32, rsi=ctypes.c_int32):
"""
# return sum of two 32-bit integers
# 64-bit Linux/MacOS call convention
#
.intel_syntax noprefix
mov rax, 0
mov eax, edi
add eax, esi
ret
"""
return ctypes.c_int32
print(add_ints(43, -1))
- Function API - powerful
add_ints = il.def_asm(
name="add_ints",
prototype=ctypes.CFUNCTYPE(ctypes.c_int32, # return value (eax)
ctypes.c_int32, # 1st param (edi)
ctypes.c_int32), # 2nd param (esi)
code="""
.intel_syntax noprefix
mov rax, 0
mov eax, edi
add eax, esi
ret
""")
print(add_ints(43, -1))
Dependencies
-
If object code is available: no dependencies outside Python standard library.
ctypes
from the standard library is needed for loading and running object code. -
If object code is not available:
as
andobjcopy
(frombinutils
) are required for compiling assembly.
Install
$ sudo python3 setup.py install
Library API documentation and call conventions
$ python3 -c 'import il; help(il)'
How it works
-
Assume that
mylib.py
contains inlined assembly. By default,il
looks for object code frommylib.py.il
. If found, that code will be executed when inlined functions are called. -
If object code is not found,
il
uses binutils:as
(assembler) andobjcopy
to compile the assembly on-the-fly and extract object code from the result. Object code is saved tomylib.py.il
for later use. -
Note:
il
does not link object code before running it. -
You can view contents of
mylib.py.il
usingil
:$ python3 -c 'import il; print(il.dump_lib("mylib.py.il", disasm=False))'
(Use
disasm=True
to disassemble the code in the dump. Requiresobjdump
.)
Debugging inlined assembly
-
Import the library, print the pid of the Python process and the address of the function that you want to debug:
>>> import mylib >>> import os >>> os.getpid() 12345 >>> print(mylib.myfunc.il_addr) 21954560
-
Attach GDB to the Python process, set a breakpoint to the address and let the Python process continue.
$ gdb -p 12345 (gdb) layout asm (gdb) break *21954560 (gdb) cont
-
Call the function in Python
>>> mylib.myfunc()
-
Now you can step assembly instructions and see register values in GDB:
(gdb) ni (gdb) info registers
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.