Windows 64位调用约定

问题描述 投票:0回答:1

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

Windows上遵循Microsoft x64调用约定[12] [13]并预引导UEFI(对于x86-64上的长模式)。它使用寄存器RCX,RDX,R8,R9作为前四个整数或指针参数(按此顺序),并将其他参数压入堆栈(从右到左)。如果64位或更少,则在RAX中返回整数返回值(类似于x86)。

在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已经设定,我需要清除它。

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

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

windows x86-64 calling-convention eflags
1个回答
2
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.