是否需要为 X64 快速调用叶函数保留 RCX?
Does RCX need be be preserved for X64 Fastcall Leaf Functions?
我有一个用 MASM64/ML64 组装的 X64 ASM 例程。它是一个独立的叶函数,不是内联汇编。它在 Visual Studio 解决方案中的 C/C++ 程序中使用。
我在 MSDN 上找到了两个关于保留寄存器的参考资料:
第一个用于内联汇编,但它特别声明在使用 __fastcall
时保留 ECX。它似乎也缺少对 X64 的处理,因为它指的是 32 位寄存器。
第二个告诉我们"RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile and must be considered destroyed on function calls"。不幸的是,它没有明确说明它们是否需要保留。 (如果你仔细观察,它使用误导而不是说明要采取的行动)。
我认为第二篇文章在这种情况下是控制的,但我想说清楚以避免混淆...是否需要为 X64 Fastcall 叶函数保留 CX/ECX/RCX?
"Using and Preserving Registers in Inline Assembly" 文章仅讨论 x86,不适用于 x86-64。
"Caller/Callee Saved Registers"文章是关于 x86-64 调用约定的,明确指出 RCX 寄存器是易失性的,因此不需要被调用者保存。
@rkhb 的评论提到 "Overview of x64 Calling Conventions" 文章是混淆的根源,大概是因为它说:
x64 just uses the __fastcall
calling convention and a RISC-based exception-handling model
但是,如果您遵循该引用中的 __fastcall
link,您会看到 "This calling convention [__fastcall
] only applies to the x86 architecture"。我认为概述文章的真正意思是说 "x64 uses a calling convention similar to __fastcall
where registers are used to pass arguments"。
我有一个用 MASM64/ML64 组装的 X64 ASM 例程。它是一个独立的叶函数,不是内联汇编。它在 Visual Studio 解决方案中的 C/C++ 程序中使用。
我在 MSDN 上找到了两个关于保留寄存器的参考资料:
第一个用于内联汇编,但它特别声明在使用 __fastcall
时保留 ECX。它似乎也缺少对 X64 的处理,因为它指的是 32 位寄存器。
第二个告诉我们"RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile and must be considered destroyed on function calls"。不幸的是,它没有明确说明它们是否需要保留。 (如果你仔细观察,它使用误导而不是说明要采取的行动)。
我认为第二篇文章在这种情况下是控制的,但我想说清楚以避免混淆...是否需要为 X64 Fastcall 叶函数保留 CX/ECX/RCX?
"Using and Preserving Registers in Inline Assembly" 文章仅讨论 x86,不适用于 x86-64。
"Caller/Callee Saved Registers"文章是关于 x86-64 调用约定的,明确指出 RCX 寄存器是易失性的,因此不需要被调用者保存。
@rkhb 的评论提到 "Overview of x64 Calling Conventions" 文章是混淆的根源,大概是因为它说:
x64 just uses the
__fastcall
calling convention and a RISC-based exception-handling model
但是,如果您遵循该引用中的 __fastcall
link,您会看到 "This calling convention [__fastcall
] only applies to the x86 architecture"。我认为概述文章的真正意思是说 "x64 uses a calling convention similar to __fastcall
where registers are used to pass arguments"。