x64调用约定中前4个参数的影子空间有什么用 [英] What is the usage for the shadow space for the first 4 parameters in x64 calling convention

查看:35
本文介绍了x64调用约定中前4个参数的影子空间有什么用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 http://msdn.microsoft.com/en-us/us-en/library/ms235286.aspxhttp://msdn.microsoft.com/en-us/us-en/library/ew5tede7.aspx调用者必须始终为 4 个寄存器参数分配足够的空间,即使被调用者没有那么多参数.始终为寄存器参数分配空间,即使参数本身从未驻留在堆栈中.

According to http://msdn.microsoft.com/en-us/us-en/library/ms235286.aspx and http://msdn.microsoft.com/en-us/us-en/library/ew5tede7.aspx The caller must always allocate sufficient space for the 4 register parameters, even if the callee doesn’t have that many parameters. Space is always allocated for the register parameters, even if the parameters themselves are never homed to the stack.

这4个寄存器参数的影子空间有什么用?

What's the usage of this shadow space for the 4 register parameters?

我反汇编了一些VS和G++编译的程序,发现被调用者一开始就将寄存器参数保存在shadow space中.例如,WinMain(HINSTANCE *hInstance, HINSTANCE *hPrevInstance, char *lpCmdLine, int nCmdShow) 函数在其开头执行以下推送:

I disassemblied some programs compiled by VS and G++, and found that the callee saves the register parameters in the shadow space at the beginning. For example, WinMain(HINSTANCE *hInstance, HINSTANCE *hPrevInstance, char *lpCmdLine, int nCmdShow) function does the following pushing at its beginning:

mov     [rsp+arg_18], r9d
mov     [rsp+arg_10], r8
mov     [rsp+arg_8], rdx
mov     [rsp+arg_0], rcx

为什么被调用者将寄存器参数保存在影子空间中?如果被调用者必须将寄存器参数保存在堆栈中,为什么他们使用寄存器传递参数而不是直接通过堆栈传递所有参数?

Why the callee saves the register parameters in the shadow space? If the callee has to save the register parameters in the stack, why they use registers to pass the parameters instead of passing all the parameters by stack directly?

推荐答案

被调用者可能需要也可能不需要保存它们,这完全取决于情况.例如,一个只返回参数总和的函数可能不需要保存它们.在这种情况下,使用寄存器可以节省存储和加载,而在另一种情况下不会产生任何开销(存储只是从调用者移动到被调用者).

The callee may or may not need to save them, that depends entirely on the situation. For example, a function that just returns the sum of the arguments might not need to save them. In this case using registers saves a store and a load, while it does not incur any overhead in the other case (the store is just moved from the caller to the callee).

如果与调用者中的局部变量一起分配影子空间实际上是免费的,并且其优点是如果被调用者需要保存参数,则结果块将与其余参数连续在堆栈上.

Allocating the shadow space is practically free if you do it together with your local variables in the caller, and has the advantage that if the callee needs to save the arguments, the resulting block will be contiguous with the rest of the arguments already on the stack.

这篇关于x64调用约定中前4个参数的影子空间有什么用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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