PyAsm-在python中嵌入汇编

PyAsm是由Python写的动态编译器,使用PyAsm还可以在Python中嵌入汇编语言,用汇编语言来编写Python函数。这听起来很疯狂,但也许你真的需要在python中使用汇编语言。起官方网站为http://members.verizon.net/~olsongt/usersGuide.html

其实很久之前就发现了PyAsm,但是初期的尝试并不成功。官方网站并没有给太多的例子,刚开始也没有完全搞懂PyAsm的原理。昨天又突然想起 PyAsm来,终于有了发现。要用好PyAsm首先要了解PyAsm,根据我的不完全理解,PyAsm中的汇编代码应该是被编译成了Python扩展,然 后读入内存,并执行。这样,如何通过PyAsm在Python中使用汇编也就比较清晰了。其实就是将汇编代码作为Python的扩展函数来写。

初次尝试PyAsm失败就是因为没法处理传入的参数,当时没有搞清楚,只是简单的使用!ARG来获取参数,而实际上PyAsm所编译的函数应当是 Python扩展函数的原型即static PyObject * ext_func(PyObject *self, PyObject *args),主要有两个参数self和args,其中args就是传入的参数列表,需要用Python API PyArg_ParseTuple来解析。

同样,PyAsm中的函数返回值则需要用Py_BuildValue来创建。

好,下面给出一个简单sum函数,求两个参数之和。

# -*- coding:utf-8 -*-
# file: test.py
#   by: bluebanboom                0(0
# mail: bluebanboom@gmail.com       ~
# date: 2008-11-06
# note:

import pyasm.excmem
from pyasm.x86asm import assembler, CDECL, STDCALL, PYTHON
from pyasm.x86cpToMemory import CpToMemory

def main():
    a = assembler()
    a.ADStr("in_fmt", "ii/0")
    a.ADStr("out_fmt", "i/0")
    a.AP("sum", PYTHON)
    a.ARG("self")
    a.ARG("args")
    a.AddLocal("x")
    a.AddLocal("y")
    #a.AI("INT 3")
    a.AI("LEA EAX, x")
    a.AI("PUSH EAX")
    a.AI("LEA EAX, y")
    a.AI("PUSH EAX")
    a.AI("PUSH in_fmt")
    a.AI("PUSH args")
    a.AI("CALL PyArg_ParseTuple")
    a.AI("ADD ESP, 0xC")
    a.AI("MOV EAX, x")
    a.AI("MOV EBX, y")
    a.AI("ADD EAX, EBX")
    a.AI("PUSH EAX")
    a.AI("PUSH out_fmt")
    a.AI("CALL Py_BuildValue")
    a.AI("ADD ESP, 0x8")
    a.EP()
   
    mem = CpToMemory(a.Compile())
    mem.MakeMemory()
    mem.BindPythonFunctions(globals())
   
    print sum(1, 2)
    print sum(2, 2)
       
if __name__ == "__main__":
    main()

上边的这个例子修改自PyAsm中的测试函数,运行后输出如下
3
4

很好,不是吗?

有个问题要注意,官方给的简单例子用的是PyAsm直接大段写代码,但这样有问题,通过调试我发现在函数的开头没有经典的

push ebp
mov ebp, esp

并没有实现官方说的This will generate the boilerplate function startup code, which consists of PUSHing the EBP register, copying the current location of ESP, and translating arguments and local variables into references via the offset of the EBP pointer.但意外的是在函数结束却有那么一段,看来是一个bug,把位置搞错了。

另外调用函数要自己清除堆栈。

上边的代码中将INT 3给注释掉,如果需要调试代码可以去掉注释,这样就是出错,然后加载调试器就可以了。

这样,在使用PyAsm的时候几乎就没有任何问题了。另外,PyAsm还可以充当编译器使用,真是强悍啊。

PeachPy 是一个用于编写高性能汇编内核的 Python 框架,可在汇编编写模块。 它自动化了一些细节,并允许使用 Python 生成重复的汇编代码序列。PeachPy 旨在简化编写优化的汇编内核,同时保留传统的汇编所有优化机会。一些特性:用于 Windows,Unix 和 Golang 程序集的通用汇编语法.PeachPy 可以直接生成 ELF,MS COFF 和 Mach-O 对象文件以及 Golang 工具链的汇编列表自动适应不同的调用约定和 ABIs用于不同平台的功能可以从汇编相同的源生成支持 Microsoft x64 ABI, System V x86-64 ABI (Linux 和 OS X), Linux x32 ABI, Native Client x86-64 SFI ABI, Golang AMD64 ABI, Golang AMD64p32 ABI自动分配寄存器PeachPy 是灵活的,而且允许在同一代码混合自动分配寄存器和硬编码寄存器汇编编程常规任务的自动化:函数 prolog 和 epilog 由 PeachPy 生成数据常量的重复数据删除 (e.g. Constant.float32x4(1.0))分析在函数使用的 ISA 扩展支持 x86-64 指令,最高可达 AVX-512 和 SHA包含 3dnow! , XOP, FMA3, FMA4, TBM 和 BMI2.不包括 x87 FPU 和大多数系统指令使用自动生成的测试 auto-generated tests 进行严格测试,以生成与 binutils 相同的操作码自动生成元数据文件具有模块依赖性的Makefile (-MMD 和-MF 选项)C 头文件生成的函数JSON 格式的函数元数据基于 Python 的元编程和代码生成多个指令流的复用(有助于软件流水线)兼容 Python 2 和 Python 3,CPythonPyPy在线 DEMO: PeachPy.IO 标签:PeachPy
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值