gpt4 book ai didi

c++ - __cdecl 导致比 __stdcall 更大的可执行文件?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:20:24 25 4
gpt4 key购买 nike

我发现了这个:

Because the stack is cleaned by the called function, the __stdcall calling convention creates smaller executables than __cdecl, in which the code for stack cleanup must be generated for each function call.

假设我有两个函数:

void __cdecl func1(int x)
{
//do some stuff using x
}

void __stdcall func2(int x, int y)
{
//do some stuff using x, y
}

main() 中:

int main()
{
func1(5);
func2(5, 6);
}

IMO,main() 负责清理对 func1(5)func2 的调用堆栈将清理对 func2(5,6) 的调用堆栈,对吗?

四个问题:

1.对于在main()中调用func1main负责清理堆栈,编译器也一样在调用 func 之前和之后插入一些代码(清理堆栈的代码)?像这样:

int main()
{
before_call_to_cdecl_func(); //compiler generated code for stack-clean-up of cdecl-func-call
func1(5);
after_call_to_cdecl_func(); //compiler generated code for stack-clean-up of cdecl-func-call

func2(5, 6);
}

2.main()中调用func2,清理堆栈是func2自己的工作,所以我假设,在调用 func2 之前或之后,不会在 main() 中插入任何代码,对吗?

3.因为func2__stdcall,所以我推测,编译器会像这样自动插入代码(清理堆栈):

void __stdcall func1(int x, int y)
{
before_call_to_stdcall_func(); //compiler generated code for stack-clean-up of stdcall-func-call
//do some stuff using x, y
after_call_to_cdecl_func(); //compiler generated code for stack-clean-up of stdcall-func-call
}

我想对吧?

4.最后,回到引用的话,为什么 __stdcall__cdecl 产生更小的可执行文件?而且 linux 中没有 __stdcall 这样的东西,对吧?是不是linux elf总是比win下的exe大?

最佳答案

  1. 它只会在调用后插入代码,即重置堆栈指针,只要有调用参数。*
  2. __stdcall 在调用点不生成清理代码,但是,应该注意编译器可以将多次 __cdecl 调用的堆栈清理累积到一次清理中,或者它可以延迟清理以防止管道停顿。
  3. 忽略此示例中的倒置顺序,不,它只会插入代码来清理 __cdecl 函数,函数参数的设置是不同的(不同的编译器生成/偏好不同的方法)。
  4. __stdcall 更像是 Windows 的东西,参见 this .二进制文件的大小取决于对 __cdecl 函数的调用次数,更多调用意味着更多清理代码,而 __stdcall 只有 1 个清理代码实例。但是,您不会看到大小增加太多,因为每次调用最多只有几个字节。

*区分清理和设置调用参数很重要。

关于c++ - __cdecl 导致比 __stdcall 更大的可执行文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9173051/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com