2012-02-18 47 views
4

我有一些程序集例程由C函数调用并从中获取参数。现在,我假设这些参数是以cdecl顺序在堆栈上传递的。这是一个公平的假设吗?假设在组合C和x86程序集时调用约定

编译器(GCC)会检测到这一点,并确保参数传递正确,或者我应该手动去声明它们的cdecl?如果是这样,如果我指定更高的优化级别,该属性是否仍然有效?

+3

不,您的汇编代码在链接时间之前不符合您的C代码。为了让C编译器对您采用的任何调用约定很聪明,时间已经太晚了。内联汇编很流行的一个原因。 – 2012-02-18 22:44:57

回答

1

这是您编写代码的平台的ABI问题。几乎所有的平台都遵循用于C调用约定和其他ABI问题的Unix System V ABI,其中包括详述所有CPU体系结构中常见ABI特性的通用ABI(gABI)文档以及特定于处理器的专用ABI(psABI)文档特定的CPU架构/系列。说到x86,这与您所称的“cdecl”相匹配。因此,从实际的角度来看,意图从C调用的x86汇编应该写成假定“cdecl”。基本上,这个调用约定的普遍性的唯一例外是Windows API函数,由于传统的Win16 dll thunk兼容性问题,它们使用自己的非标准“stdcall”调用约定;尽管如此,x86 Windows上的“默认”调用约定仍然是“cdecl”。

编写要从C中调用的asm时,更重要的问题是符号名称是否应加前缀下划线。这在平台之间差别很大,总的趋势是基于ELF的平台不使用前缀,并且大多数其他平台都这样做...

0

快速和肮脏的方法是创建一个虚拟的C函数,匹配你想要实现的asm函数,在虚函数函数中用传入的参数做一些事情,这样你就可以区分它们,编译然后拆开。不是万无一失的,但经常工作。