【问题标题】:Does a function gets stack frame when called using a function pointer in C?在 C 中使用函数指针调用函数时是否会获取堆栈帧?
【发布时间】:2021-10-27 04:40:53
【问题描述】:

如果函数指针指向内存代码段内的函数,当使用函数指针调用该函数时,该函数是否会获得自己的堆栈帧。

【问题讨论】:

  • 我的印象是,您认为在 C 中通过函数名称调用函数与通过函数指针调用函数是有区别的。实际上,一旦 C 被编译成机器代码,所有函数调用最终都会成为 call 指令,它将函数的第一条指令的地址作为操作数(或包含该地址的寄存器)。实际上,每次你调用一个函数时,你都在使用它的地址(语言只是对你隐藏它)。
  • 在机器码中,从函数指针调用函数与直接调用没有区别。
  • 注意:C99 标准包含 0 次提及单词 stack,另外 0 次提及单词 frame。从技术上讲,您可以有一个不使用堆栈帧的实现。所以“与普通函数调用相同”,请注意这可以是或否取决于编译器。

标签: c function


【解决方案1】:

tl;dr - 是的,与直接调用函数时没有什么不同。


如果我们有这样的代码:

void func() {
}

typedef void (*func_ptr)();

int main() {
    func_ptr ptr = func;
    ptr();
}

在汇编中,对ptr() 的调用将类似于become

mov     QWORD PTR [rbp-8], OFFSET FLAT:func
mov     rdx, QWORD PTR [rbp-8]
call    rdx

你可以看到call rdx 等价于call func(因为rdx == func)。堆栈帧由程序集中 call 推送到堆栈的信息和函数本身在其序言中推送的信息定义 - 这两者在直接调用 (call func) 或间接调用时是等效的一个函数指针 (call rdx)。

【讨论】:

    【解决方案2】:

    是的。对于一个函数f和一个指向f的函数指针fp,函数调用f的唯一区别() 和 fp() 是在后者调用之前有一个额外的(隐式)指针间接步骤。

    【讨论】:

      猜你喜欢
      • 2013-10-12
      • 2012-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 2011-01-19
      • 2017-11-24
      相关资源
      最近更新 更多