使用寄存器而不保留它们? (部件)

Use registers without preserving them? (assembly)

在Windows调用约定之后,只有RAX、RCX、RDX、r8和r9可以不用保留(称为volatile),其余称为nonvolatile(必须保留)。

使用非易失性寄存器而不保留它们有什么问题吗? (我经常这样做,到目前为止我还没有遇到任何问题)

调用约定说只有 RCX、RDX、r8 和 r9 用于传递整数参数,额外的应该在堆栈上传递。

使用 r10 作为第五个参数而不是堆栈有什么缺点吗? (知道内存至少比寄存器慢100倍,我尽量把寄存器用到极致)

当有整整十几个额外的寄存器时,为什么调用约定会在 4 个寄存器处停止以传递参数?

您 "need" 保留非易失性寄存器,以便函数的调用者可以依赖它来保持这些寄存器中的值不变。

另外,想一想,如果您编写一个使用这些寄存器而不是堆栈作为参数的函数,调用者必须在哪里存储他的值? 堆栈,在某些时候没有办法绕过它。

您确实可以将非易失性寄存器压入堆栈并在需要时将它们弹出。

大声写出来作为答案,因为我认为需要强调@Michael Petch(和其他人)的观点,供将来参考,不只是评论。

违反 ABI 不是坏习惯,这完全是错误的
就像引用悬垂指针、写入 const 内存等错误一样。


背后的原因很明显:调用者通常会将临时数据保存在非易失性寄存器中,它可以是字符串的索引、求和、加密哈希或其他任何内容。


如果你控制了 ABI,你就制定了规则;如果你不这样做,你就不会。