首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对于X64 Fastcall叶子函数,需要保留RCX吗?

对于X64 Fastcall叶子函数,需要保留RCX吗?
EN

Stack Overflow用户
提问于 2015-10-16 21:08:51
回答 2查看 397关注 0票数 2

我有一个与MASM64 64/ML64 64组装的X64 ASM例程。它是一个独立的叶函数,并且不是内联程序集。它用于Visual解决方案中的C/C++程序中。

我找到了关于在MSDN上保存寄存器的两个引用:

第一个是内联程序集,但它特别声明在使用__fastcall时保留ECX。它似乎也缺乏对X64的处理,因为它引用了32位寄存器.

第二部分告诉我们"RAX、RCX、RDX、R8、R9、R10、R11被认为是易失性的,必须在函数调用时考虑销毁“。不幸的是,它没有明确说明是否需要保留这些文件。(如果你仔细观察,它使用的是误导,而不是陈述要采取的行动)。

我认为第二篇文章在这件事上很有控制力,但我想澄清一下,以避免混淆.CX/ECX/RCX是否需要为X64 Fastcall叶函数保留?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-16 23:15:17

“在内联装配中使用和保存寄存器”文章只讨论x86,不适用于x86-64。

“呼叫者/Callee保存登记册”文章是关于x86-64调用约定的,并且清楚地指出RCX寄存器是不稳定的,因此不需要被被调用者保存。

@rkhb的一条评论提到,“x64呼叫约定概述”的文章是造成混乱的根源,大概是因为它说:

x64只使用__fastcall调用约定和基于RISC的异常处理模型。

但是,如果您在引用中遵循__fastcall链接,您将看到它说,“此调用约定__fastcall仅适用于x86体系结构”。我认为概述文章实际上意味着,"x64使用类似于__fastcall的调用约定,其中寄存器用于传递参数“。

票数 6
EN

Stack Overflow用户

发布于 2022-07-25 08:35:10

因为调用者必须假定函数破坏了这些寄存器,所以被调用者可以在不保存它们的情况下销毁它们。也就是说,这些寄存器是易失性,也就是所谓的失败。它适用于64位寄存器的整个列表,包括所有的arg传递寄存器.

函数内部与周围C/C++代码的内联__asm接口本质上与函数之间的ABI /调用约定无关。例如,x86 (32位) fastcall有调用失败的ECX,就像对arg传递寄存器一样。32位fastcall是Windows x64 fastcall之外的一个单独的调用约定,所以您所读到的关于32位fastcall的任何内容都是64位的权威。

MSVC内联asm支持是如此脆弱,并且在他们的编译器中很难实现。,他们需要您的asm在带有寄存器args的函数中跳转,因为它们的编译器太笨,无法像普通变量那样将它们保存在安全的地方。例如,你联系的那个医生说:“这会在__asm块的函数中产生问题,因为函数无法判断哪个参数在哪个寄存器中。”但这显然是胡说八道,因为电话会议把这一点打倒了。否则,编译器无法使asm在不使用内联asm的函数中访问其参数。(或者,这是对编译器中的内联asm代码不是为了处理寄存器-arg调用约定而编写的,而且从来没有重新编写的事实的描述。)其他编译器,包括clang-cl,没有这个问题。

这就是所有关于保持ECX的胡说八道的地方,与asm中函数相互调用的方式无关,只有在使用MSVC的易碎内联asm时对函数内部的要求。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33179577

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档