函数参数被放置在栈上,但编译器可以通过使用可选寄存器来优化此任务。如果只有1-2个参数,这种优化会很有意义,而不是当有256个参数时(虽然没有人想要拥有最大数量的参数)。
如何找出某个编译器(如gcc)的参数限制(参数数量),以确保使用此优化?
函数参数被放置在栈上,但编译器可以通过使用可选寄存器来优化此任务。如果只有1-2个参数,这种优化会很有意义,而不是当有256个参数时(虽然没有人想要拥有最大数量的参数)。
如何找出某个编译器(如gcc)的参数限制(参数数量),以确保使用此优化?
函数参数被放置在堆栈上,但编译器可以通过使用可选寄存器来优化此任务。
正如FrankH在他的评论中所说,以及我在我的答案中要说的,系统的应用二进制接口决定了如何将参数传递给函数-这被称为该平台的调用约定。
复杂化问题的是,x86 32位实际上有几种。这是历史遗留问题,源于当Win32到来时,每个人都疯狂地做着不同的事情。
因此,是的,您可以通过以这种方式编写函数调用来“优化”,但不,您不应该这样做。您应该遵循您的平台的标准。因为诚实的事实是,堆栈访问速度可能并没有使您的代码变得非常缓慢,以至于您需要与系统中的其他人不兼容。
ABIs/标准调用约定的必要性是什么?在使用处理器寄存器、堆栈等方面,应用程序必须就什么意味着什么以及它们应该放在哪里达成一致。如果一个函数决定所有参数都在寄存器中,而另一个函数决定一些参数在堆栈上,它们如何相互操作?此外,您可能会遇到术语“scratch registers”,意思是“那些您不需要恢复的寄存器”。如果您调用一个期望保留某些寄存器的函数会发生什么?-OX
),如果你认为它有帮助并转储汇编代码以检查是否真正那么关键。对于公开可见的函数,这在ABI标准中有所说明。对于无法从外部引用的函数,所有情况都不确定。
如果你想了解编译器的细节,你需要阅读精细的手册。如果你很幸运,你会在函数调用约定的描述中找到答案。否则,对于像 gcc
这样的开源编译器,你可能需要阅读它的源代码。
__cdecl
、__fastcall
、__stdcall
等等)主要是 x86/DOS/Windows 特有的事情。 - FrankH.