使用 void(*)(void) 指针调用 void function(int) 并准备使用参数堆栈

标签 c gcc stack function-pointers compiler-flags

我有一个 void(*)(void) 函数指针,指向一个实际上是 void f(int) 的函数。关键是,此时我不知道它是什么函数,所以我不能简单地将它转换为void(*)(int)。我想我可以简单地用函数的参数准备堆栈。

#include <stdio.h>

void func(int x) {
    printf("%p : %d\n", &x, x);
}

int main(int argc, char* argv[]) {
    int* ptr = &argc - 8;
    *ptr = -1;
    printf("%p : %d\n", ptr, *ptr);

    void (*f)(void) = (void(*)(void)) &func;
    f();

    return 0;
}

返回:

0x7ffd72ec204c : -1
0x7ffd72ec204c : 0

我希望它返回 -1 两次。但是,gcc 似乎添加了一些代码来在调用函数时清除堆栈,这就是为什么 func() 显示 0 的原因。

是否有某种编译器标志可用于禁用它?

我正在使用 gcc (Debian 4.9.2-10) 4.9.2,但如果我能让它在任何编译器中工作就足够了!我的名字是 Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01-17) x86_64 GNU/Linux

我读过有关 MUST_PASS_IN_STACK 的内容 - 这有帮助吗?如果是,我该如何使用它?

我知道这不是特别好的做法。这只是一个理论练习。

最佳答案

你试图做的是未定义的行为。在标准 C 中,不可能在运行时构造具有任意参数类型的函数调用。您也不能假设变量最终出现在堆栈中的布局(如果有的话)。您甚至不能假设函数参数是在堆栈上传递的。

如果您想做这样的事情,请考虑查看像 libffi 这样的库它通过为每个平台和每个操作系统实现不同的解决方案来做类似的事情。

关于使用 void(*)(void) 指针调用 void function(int) 并准备使用参数堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35088454/

相关文章:

c# - 构建系统选择?

c - C 中的前/中/后缀遍历(包括数组)

C 同时(条件); body 没有指示

c - (Enum) -1 在 C 中代表什么值?如何在 Swift 中编写它?

c - 为什么 gcc 不为函数调用引用 PLT?

ios - 适用于 iOS 目标的 Ada 交叉编译器

gcc - 如何让 -flto 工作?

c - C语言中栈的push方法的实现

c++ - 变量周围的堆栈已损坏,visual studio 2010 问题

c++ - 在调用者的堆栈上分配内存