__cdecl比__stdcall产生更大的可执行文件? [英] __cdecl results in larger executable than __stdcall?

查看:77
本文介绍了__cdecl比__stdcall产生更大的可执行文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了这一点:


由于堆栈已被调用函数清除,因此__stdcall
调用约定会创建可执行文件,其中必须为每个函数调用生成
堆栈清理代码

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.

假设我有2个函数:

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)的调用的堆栈,对吗?

IMO, it is main()'s responsibility to clean up the stack of the call to func1(5), and func2 will clean up the stack of the call to func2(5,6), right?

四个问题:

1。用于调用 main()中的 func1 ,清理堆栈是主要的责任,因此编译器将在之前和之后插入一些代码(清理堆栈的代码)。调用 func ?像这样:

1.For the call to func1 in main(), it's main's responsibility to clean up the stack, so will compiler insert some code (code to clean up the stack) before and after the call to func? Like this:

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。用于调用 func2 main()中的c $ c>,它是 func2 自己的工作,它用来清理堆栈,所以我想,在调用 func2 之前或之后,不会在 main()中插入任何代码,对吗?

2.For the call to func2 in main(), it's func2's own job to clean up the stack, so I presume, no code will be inserted in main() before or after the call to func2, right?

3。因为 func2 __ stdcall ,所以我想,编译器会自动插入代码(清理堆栈),如下所示:

3.Because func2 is __stdcall, so I presume, compiler will automatically insert code (to clean up the stack) like this:

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 这样的东西,对吗?

4.Finally, back to the quoted words, why __stdcall results in smaller executable than __cdecl? And there is no such a thing as __stdcall in linux, right? Does it means linux elf will be always larger than exe in win?

推荐答案


  1. 这只会使Windows elf在win中总是比exe大吗?只要在调用参数之后的位置,在调用之后插入代码即可重置堆栈指针。*

  2. __ stdcall 不会生成任何代码但是,应该注意,编译器可以将多个 __ cdecl 调用中的堆栈清理累积到一个清理中,或者它可以延迟清理以防止管道停顿

  3. 在此示例中,忽略倒序,不,它只会插入代码来清理 __ cdecl 函数,设置函数参数是不同的(不同的编译器生成/更喜欢使用不同的方法)。

  4. __ stdcall 更多的是Windows,请参见。二进制文件的大小取决于对 __ cdecl 函数的调用次数,更多的调用意味着更多的清理代码,其中 __ stdcall 只有1个清除代码的单数实例。但是,您不应看到大小增加太多,因为每次调用最多只有几个字节。

  1. It'll only insert code after the call, which is to reset the stack pointer, so long as there where call arguments.*
  2. __stdcall generates no cleanup code at the call site, however, it should be noted that compilers can accrue stack cleanup from multiple __cdecl calls into one cleanup, or it can delay the cleanup to prevent pipeline stalls.
  3. Ignoring the inverted order in this example, no, it'll only insert code to cleanup the __cdecl function, setting up of function arguments is something different (different compilers generate/prefer different methods).
  4. __stdcall was more a windows thing, see this. the size of the binary depends on the number of calls to the __cdecl funcs, more calls means more clean up code, where as __stdcall has only 1 singular instance of cleanup code. however, you shouldn't see that much size increase, as at most you have a few bytes per call.

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

*Its important to distinguish between cleanup and setting up call parameters.

这篇关于__cdecl比__stdcall产生更大的可执行文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆