0

根据我在调用 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设置了方向标志并且我需要清除它的事实。

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

或者这可能会导致其他问题。有人知道在这种情况下调用的约定吗?

4

1 回答 1

3

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

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

于 2017-05-09T08:58:58.503 回答