将C地址称为无原型的函数

时间:2013-08-25 09:24:01

标签: c assembly 64-bit

我需要通过知道地址来调用C中的函数,而不需要信息 在它原型上(我不能将它转换为C函数指针)。

我对此功能的信息是地址。

我也知道我要传递给它的参数(感谢void指针)和 arguments数组的大小(通过void指针访问)。

我也想尊重C调用约定。对于x86版本,我非常喜欢 知道如何做(在堆栈上分配空间,将参数复制到 那个空间,最后调用函数)。

问题在于x64约定(现在是Linux),参数是 通过寄存器。我不知道要填充的每个参数的大小 适当注册,我只知道参数数组的大小。

另外,我不想依赖gcc所以我似乎不能使用__builtin_apply 不标准,也很黑。

我想编写自己的代码来支持多编译器以及 学习有趣的东西。

所以基本上,我想写的功能与原型相同 __builtin_apply是:

void *call_ptr(void (*fun)(), void *params, size_t size);

我还希望代码用C语言编写(感谢asm inline)或纯x64 asm。

那么有没有办法正确地做到这一点,并尊重呼叫 惯例 ?或者在不知情的情况下使用x64约定这是不可能的 确切地说是函数的原型?

2 个答案:

答案 0 :(得分:2)

特别是对于Linux上的x64调用约定,这根本不起作用。

原因是非常复杂的调用约定。

一些例子:

void funcA(float64 x);
void funcB(int64 x);

在这两种情况下,值“x”以不同的方式传递给函数,因为浮点和整数被传递给不同寄存器中的函数。

void funcC(float64 x,int64 y);
void funcD(int64 y,float64 x);

在这两种情况下,参数“x”和“y”的顺序不同。但是它们以相同的方式传递给函数(两个函数对“x”使用相同的寄存器,对“y”使用相同的寄存器。)

结论:要创建一个能够执行所需操作的函数,您必须将包含每个参数的参数类型的字符串传递给汇编程序函数。参数的数量/大小绝对不够。但是它肯定是可能的 - 只要它只能在Linux上运行。

答案 1 :(得分:0)

我认为,你的所有决定都不会支持多编译器,因为将参数传递给函数的机制(寄存器,它们的顺序,堆栈,内存) - 它的编译器依赖特性......