开发者

Unexplained stack allocation in native C code built for x64 under Visual Studio 2010

开发者 https://www.devze.com 2023-01-07 02:49 出处:网络
I am trying to use CL 16.0 for x64 (VS 2010) to produce some readable 64-bit ASM code for an example, but CL insists on preallocating a ton of stack space (28h bytes), with the following line:

I am trying to use CL 16.0 for x64 (VS 2010) to produce some readable 64-bit ASM code for an example, but CL insists on preallocating a ton of stack space (28h bytes), with the following line:

sub rsp, 40 ; 00000028H (actual value depends on number of local vars of course)

Question is, how can I disa开发者_Go百科ble this behavior? It is difficult to explain to the class and I like to show them clean, explicable code... My assumption is that "sub rsp, XXX" should allocate the exact space required by the local variables in the function.

Surely it doesn't need that extra space. On x86, this behavior seems to be controlled by the edit-and-continue switches (/Zi vs. /ZI), but these don't have any effect in the x64 case. Any idea how to make x64 CL only allocate as much stack as it actually needs?

Thanks in advance!


It'd be easier if you showed the source code that produced this, but 40 bytes is not that much for a 64-bit machine. That's only five longs or pointers. Another thing to take into account is alignment for local variables - the compiler probably pads them for optimal access.

Edit:

Hmm, this is indeed a bit puzzling. Running this through GCC doesn't result is such stack grab. My suspicion is that this is compiler-specific exception handling prolog requirement (do you see some weird-looking labels before and after the stack allocation in the generated code?).

Here are couple of MSDN links you might find useful:

  • Overview of x64 Calling Conventions
  • Stack Allocation

I don't have a Windows box to test, but try /favor:??? and see if cranking the optimization level up a bit eliminates this. It's a leaf function after all.

Also, comments formatting on SO sucks, put the code into the question itself.


It is called shadow space:

every function in Win64 can (although is not obliged to) store values of 4 registers there. This is done at least for two reasons

  1. in a large function, it is too wasteful to allocate an entire register (much less 4 registers) for an input argument, so it will be accessed through the stack;

  2. the debugger always knows where to find the function's arguments at break.

So, some large functions may save input arguments in "shadow space" for future use, while small functions like ours may not. It is the caller who allocates space in the stack for "shadow space".

0

精彩评论

暂无评论...
验证码 换一张
取 消