我需要通过知道地址来调用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约定这是不可能的 确切地说是函数的原型?
答案 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)
我认为,你的所有决定都不会支持多编译器,因为将参数传递给函数的机制(寄存器,它们的顺序,堆栈,内存) - 它的编译器依赖特性......