Windows 64位调用约定

时间:2017-05-09 02:33:21

标签: windows x86-64 calling-convention eflags

根据我在调用Windows函数时可以找到的文档,以下内容适用: -

  

Windows上遵循Microsoft x64调用约定[12] [13]   并预启动UEFI(对于x86-64上的长模式)。它使用寄存器RCX,   RDX,R8,R9用于前四个整数或指针参数(在那里   订单),并将其他参数推入堆栈(右到   剩下)。如果,则在RAX中返回整数返回值(类似于x86)   64位或更少。

     

在Microsoft x64调用约定中,它是调用者的   负责在堆栈上分配32个字节的“影子空间”   在调用函数之前(无论实际的数量是多少)   使用的参数),并在调用后弹出堆栈。影子   空间用于溢出RCX,RDX,R8和R9,[14]但必须制作   适用于所有功能,即使是少于四个功能的功能   参数。

     

寄存器RAX,RCX,RDX,R8,R9,R10,R11被认为是易失性的   (呼叫者保存)。[15]

     

寄存器RBX,RBP,RDI,RSI,RSP,R12,R13,R14和R15是   被认为是非易失性的(被调用者保存)。[15]

所以,我很高兴地调用kernel32,直到在某些情况下对GetEnvironmentVariableA的调用失败。我终于追溯到方向标志DF被设置的事实,我需要清除它。

到目前为止,我还没有找到任何提及这一点,并想知道在电话会议之前总是清楚它是否明智。

或者这可能会导致其他问题。有人知道在这个实例中调用的约定吗?

1 个答案:

答案 0 :(得分:2)

windows假设已清除direction flag。尽管在文章中只讨论了 C 运行时,但对于整个窗口来说都是如此(想想因为windows代码本身主要是用c / c ++编写的)。因此,当您的程序开始执行时 - 您可以假设 DF 为0.通常您不需要更改此标志。但是如果你在某个内部例程中临时更改它(设置为1),则必须在调用任何windows api或任何外部模块之前通过 cld 清除它(因为它假定 DF 是0)。

在开始执行时所有窗口中断都清除 DF 为0 - 所以这是安全的临时设置 DF 在自己的内部代码中为1,main - 在任何外部调用之前将其重置为0。