【问题标题】:Why does VS2013 compile a function-call into two instructions instead of one?为什么VS2013将函数调用编译成两条指令而不是一条?
【发布时间】:2014-10-07 23:01:31
【问题描述】:

这是一个简单的程序:

void func()
{
    printf("hello");
}

int main()
{
    printf("%p",func);
    func();
    return 0;
}

越过printf("%p",func) 行,我得到00F811AE 打印在控制台上。

拆线func(),给我call _func (0F811AEh) - 到目前为止一切顺利。

但是反汇编func的内容,第一条指令出现在地址00F813C0

所以我“去看看”地址 00F811AE 上有什么,并在那里找到了 jmp func (0F813C0h)

总而言之,函数调用似乎被编译为两条指令:

call _func (0F811AEh)
jmp   func (0F813C0h)

为什么 VS2013 编译器使用两条指令而不是一条指令?

看来一个jmp 就可以完成这项工作。我问这个是因为我觉得其他编译器以类似的方式执行它(当然取决于底层硬件架构)。

谢谢

【问题讨论】:

标签: c++ c compiler-construction compilation function-call


【解决方案1】:

了解“thunking”:http://en.wikipedia.org/wiki/Thunk

在您的示例中使用“thunking”的一个好处是您的代码的其余部分将始终调用 func,但任何执行相同角色的函数都可以注入到地址 0x00F811AE 的调用中。 p>

尝试将 func 设为 static,看看是否有任何变化。

【讨论】:

  • +1 具体来说,如果 printf() 是从 dll 动态加载的,则可以在内存中的某个位置修补该地址,并且所有对它的调用都会从那里找到它....
  • barak manos:不客气。另外值得考虑的是,如果确实是 thunk,则 thunk 可能正在处理调用约定差异。
  • 还值得一提(根据我的问题的一些 cmets 中提供的链接),您可以通过项目的链接器设置将其从两条指令减少到一条指令。
  • 只有当您链接到动态 RTL 时才会发生这种情况?
  • 是的,声明函数static将它从两条指令减少到一条指令,这证明这是一个链接问题,因为static函数可以在链接之前解决(即在编译期间)。
猜你喜欢
  • 1970-01-01
  • 2020-08-04
  • 2020-03-26
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 2014-11-06
  • 2018-05-10
  • 1970-01-01
相关资源
最近更新 更多