【问题标题】:How to get the return address of a function in C?如何在C中获取函数的返回地址?
【发布时间】:2020-11-02 19:16:31
【问题描述】:

我有一个函数叫做:

doSomething()

我的理解是:在汇编中,this会跳转到函数位置,并将函数的返回地址存储在某个寄存器中,这样函数完成后,程序计数器可以返回到主程序。

如何获取该函数的返回地址并将其放入变量中以便我可以使用它?

__builtin_return_address 似乎不起作用。当我把它翻译成汇编时,它不知道该怎么做。我相信我不能使用 GCC。我什至没有使用 printf,因为它不是标准 C 库的一部分。

目前,我试图通过在这个变量中放入各种数字来猜测它的返回地址是什么。

【问题讨论】:

  • C 语言没有定义实现细节,如返回地址、堆栈等。它确实定义了语言结构的语义(行为)。如果不使用程序集或一些低级(和特定于编译器的)内在函数,恐怕你无法获得返回地址。你想用退货地址做什么?也许有一些 C 功能可以用来实现你想要的。
  • "将函数的返回地址存储在某个寄存器中" 大多数实现会将返回地址存储(推送)到堆栈中。 RET 指令然后获取(弹出)地址并跳转到它。
  • 你想用这个地址做什么?注意,它只存在于doSomething在执行的时候,也就是说,如果你完全可以得到一个函数的返回地址,那么你只能在函数本身内部得到它。
  • 你可能想看看'#include `中的setjump()longjump(),它们是返回到直接调用函数以外的任何东西的可移植方式。
  • 没有可移植的 C 方案来获取函数的返回地址。

标签: c


【解决方案1】:

使用gcc,您可以使用__builtin_return_address,请参阅https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html

【讨论】:

    【解决方案2】:

    另一个用户在这里发布了关于使用 gcc 的帖子,我同意,但将其存储为变量只是使用 void 数据类型,有点像这样:

    void *addr = __builtin_extract_return_addr (__builtin_return_address (0));

    【讨论】:

      【解决方案3】:

      C 和 C++ 支持function pointers:

      C 示例:

      int sum (int num1, int num2) {
        return num1 + num2;
      }
      
      int (*f2p) (int, int);
      
      int main (int argc, char (argv[]) {
          f2p = sum;
          printf ("sum=%d\n", f2p(10, 13));
          return 0;
      }
      

      在 C++ 中,您将使用 std::function

      这是一个很好的教程:

      https://www.learncpp.com/cpp-tutorial/78-function-pointers/

      您确实需要担心函数的二进制内存地址才能使用函数指针。如果您出于任何原因想要;只需将地址(例如上面的“fp2”)转换为数字即可。


      我建议使用“函数指针”来参数化被调用者的地址。

      按照 Persixty 的建议,您可以使用 setjmp()/longjmp() 来参数化调用者的地址。

      当然,你也可以使用inline assembly来完成。

      问:这有助于回答您的问题吗?

      【讨论】:

      • 这不能回答问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      • 2014-07-12
      • 1970-01-01
      • 2013-07-25
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      相关资源
      最近更新 更多