使用内联汇编器从 GCC 中的共享库调用函数
Posted
技术标签:
【中文标题】使用内联汇编器从 GCC 中的共享库调用函数【英文标题】:Call function from shared library in GCC with inline assembler 【发布时间】:2012-02-22 19:41:12 【问题描述】:我已经创建了共享库(将像插件一样使用)。有很多函数,比如a
extern "C" long __attribute__ ((__cdecl__)) SumAgrs(long X, long Y, long Z, long *Out)
*Out = X + Y + Z;
return 0;
我想在 C++(GCC,Linux)中调用这个库中的函数,但不是在编译时。当我使用内联汇编程序时,“push”指令会破坏局部变量,我不知道如何修复它。
typedef int (*FARPROC)();
void *dl_handle = dlopen("plugin.so", RTLD_LAZY);
FARPROC proc = (FARPROC)dlsym(dl_handle, "SumAgrs");
long result;
asm("leal %0, %%eax\n\r" \
"pushl %%eax" : : "m" (result));
asm("pushl $10");
asm("pushl $15");
asm("pushl $20");
asm("call *%0" : : "m" (proc));
结果二进制文件包含类似 call *24(%esp) 的内容。所以我的 pushl 更改 %esp 和 call 导致分段错误。但是如何避免这种行为呢?
谢谢
【问题讨论】:
【参考方案1】:看看 libffi:“一个可移植的外部函数接口库”
“libffi 库为各种调用约定提供了一个可移植的高级编程接口。这允许程序员在运行时调用调用接口描述指定的任何函数。”
http://sourceware.org/libffi/
【讨论】:
【参考方案2】:实际上,你不需要汇编程序来调用函数:
extern "C"
typedef long __attribute__ ((__cdecl__)) (*Proc)(long X, long Y, long Z, long *Out);
void *dl_handle = dlopen("plugin.so", RTLD_LAZY);
Proc proc = (Proc)dlsym(dl_handle, "SumAgrs");
proc(...); // call
请注意,无论您使用 c 代码还是使用 ASM 内联调用函数,您的调用代码都是在 编译 时间生成的。您不能将string
变量传递给asm
,因为您的asm
内联代码应该在程序编译期间生成。这意味着你不能这样做
std::string asm_code;
std:: cin >> asm_code;
asm(asm_code);
【讨论】:
函数将从脚本中调用,参数存储在数组中。所以编译时“调用”不是解决方案。 no no,使用 ASM 内联,代码将在运行时生成。例如(伪代码): foreach (params) push parm; 调用函数; @user1173308,你不能那样做!您永远无法确定,foreach(params)
没有在其中使用堆栈指针,当然,它不假设您会手动更改它! 不要写这样的代码以上是关于使用内联汇编器从 GCC 中的共享库调用函数的主要内容,如果未能解决你的问题,请参考以下文章