【问题标题】:windows 64bit calling conventionwindows 64位调用约定
【发布时间】:2017-10-07 04:36:14
【问题描述】:

根据我可以找到的关于调用 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被设置,我需要清除它的事实。

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

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

【问题讨论】:

    标签: windows x86-64 calling-convention eflags


    【解决方案1】:

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

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

    【讨论】:

    • 您还需要确保在函数返回之前清除 DF。
    猜你喜欢
    • 1970-01-01
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    相关资源
    最近更新 更多