【问题标题】:How to declare a function with variable arguments to be stdcall?如何将具有可变参数的函数声明为stdcall?
【发布时间】:2018-07-29 19:08:46
【问题描述】:

现在我正在设计一个函数f(index,...),它将调用函数数组中的 #index 条目并传递其余参数。如果您将函数数组视为服务列表,f 就像一个服务分发器。

f 是用汇编语言编写的。它弹出第一个参数index,然后计算出对应的目标函数地址和jmp到它。

如果我将n 参数传递给f,则在从目标函数返回时,堆栈只会保存n-1 参数,因为index 在中途弹出。因此,我不能使用cdecl 约定,否则调用者会错误地清理堆栈中的n 参数。

stdcall 应该可以工作。但问题是,由于f可变参数,gcc 似乎__attribute__((stdcall)) f(index,...) 不合理并将其恢复为cdecl

那么请谁能告诉我如何将f 声明为stdcall

【问题讨论】:

    标签: c gcc calling-convention stdcall


    【解决方案1】:

    我不认为使用 stdcall 可以解决您的问题,因为无论如何您都必须恢复堆栈才能让您的函数在堆栈上找到返回地址。

    不要将index 从堆栈中弹出,而是将其留在那里。并且要么修改你的目标函数以忽略第一个参数,要么在调用目标函数之前将所有其他参数向左移动一个位置

    【讨论】:

    • 当然修改目标函数以添加虚拟参数是可行的,但不够美观。而且我无法移动所有其他参数... 因为f 不知道总共传递了多少个参数。 stdcall 应该可以工作。在f的实现中,运行leave恢复espebp,然后pop返回地址注册#1,保存index,然后将其替换为#1(现在堆栈构造良好)。最后它根据index jmp 到目标。目标的stdcall 将正确清理其余n-1 参数。
    • 'f' 必须是线程安全的吗?在调用f 之前,将f 包装在一个将index 保存到全局变量的宏中。或者您可以使用一些内联汇编在寄存器中传递index
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多