我理解为Micrsoft和System V AMD64 ABI传递64位代码的32位和64位整数(和指针),浮点数和双精度的调用约定。但是我不清楚复合数据类型的调用约定是什么。
更清楚的是,在具有外部链接的函数(即不是static inline
函数)中按值传递结构,类和联合的调用约定是什么?我特别感兴趣的是简单的结构,比如
typedef struct doublefloat { float hi; float lo; } doublefloat;
typedef struct doubledouble { double hi; double lo; } doubledouble;
typedef struct int128 { int64_t hi; int64_t lo; } int128;
doublefloat foof(float a, float b);
doubledouble food(double a, double b);
float foo3(doubledouble a, doubledouble b);
int128 fooi(int64_t a, int64_t b);
这是我在GCC中观察到的(使用-O3)
foof
返回hi
,lo
打包到XMM0
的前64位。 food
将hi
和lo
返回XMM0
和XMM1
。foo3
在hi
,lo
,a
,b
中XMM0
和XMM1
传递XMM2
和XMM3
和fooi
。hi
将lo
和static inline
返回到rda和rdx Agner Fog描述了每个编译器的详细信息(与观察结果一致) http://www.agner.org/optimize/calling_conventions.pdf
参见表6.传递结构,类和联合对象的方法和 表7.返回结构,类和联合对象的方法。
对于64位代码,他的表分为Windows和Linux / BSD / Mac而不是每个编译器,因此这对我来说意味着复合数据类型有一些标准。这是正确的还是每个编译器或编译器的每个版本可能定义的复合数据类型的传递和返回(即可能随下一个版本而改变)。
请注意,我了解到在实践中,在许多情况下{{1}}最好使用{{1}}。还要注意,即使C没有类,我仍然对如何通过C中的值传递结构和联合感兴趣,而不仅仅是C ++,这就是我包含C标记的原因。
答案 0 :(得分:2)
确实存在一些标准。例如,SystemV AMD64 ABI document描述了一些详细的聚合传递参数(从第17页开始)。我不会在这里复制文本的相关部分,因为有几页。
并非所有平台都有可能记录得很好。