System V AMD64结构类型参数调用约定

时间:2016-12-19 16:06:42

标签: assembly struct x86-64 calling-convention

我正在阅读有关System V AMD64呼叫约定的内容。它有一个部分,它在类中对函数的参数进行分类,其中一些是INTEGER,SSE,SSEUP,NO_CLASS,MEMORY等。

我无法理解它如何对聚合类型(即结构,联合和数组)进行分类。以下是对这些规则进行分类所遵循的规则。

规则:

  1. 如果对象的大小大于8个八位字节,或者它包含未对齐的字段,则它具有类MEMORY 12。

  2. 如果C ++对象具有非平凡的复制构造函数或非平凡的析构函数13,则它通过不可见的引用传递(该对象在参数列表中被具有类INTEGER的指针替换)14

  3. 如果聚合体的大小超过单个八字节,则每个都单独分类。每个八字节都被初始化为NO_CLASS类。

  4. 对象的每个字段都是递归分类的,因此始终考虑两个字段。结果类是根据八字节中的字段类计算的:

    • (a)如果两个类都相等,那么这就是结果类。
    • (b)如果其中一个类是NO_CLASS,则生成的类是另一个 类。
    • (c)如果其中一个类是MEMORY,则结果是MEMORY类。
    • (d)如果其中一个类是INTEGER,则结果为INTEGER。
    • (e)如果其中一个类是X87,X87UP,COMPLEX_X87类,则MEMORY用作类。
    • (f)否则使用SSE类。
  5. 然后完成合并后清理:

    • (a)如果其中一个类是MEMORY,则传入整个参数 存储器中。
    • (b)如果X87UP前面没有X87,则传入整个参数 存储器中。
    • (c)如果聚合体的大小超过两个八字节且前八个 - 字节不是SSE或任何其他八字节不是SSEUP,整个参数 在记忆中传递。
    • (d)如果SSEUP前面没有SSE或SSEUP,则转换为SSE。
  6. 我的问题在于理解规则3,4,5以及它们如何相互适用。

    以下是一个例子,这些规则如何适用于B?

    struct A{
        int a;
        long b;
        char c;
    };
    
    struct B{
        char a;
        A b;
        short* c;
    };
    

    我对它的看法是:

    首先,sizeof(B) < 64和我假设的字段布局正确对齐。因此,规则1不适用于此。

    其次,规则2也不适用。

    然而,在这里,对我来说是令人困惑的部分,此时,我理解它的方式,规则3,4都可以应用。所以有两条路径:

    1. 第一条路径是遵循规则3.规则3可以应用于sizeof(B) > 8,因此它告诉我将B对象分解为它所组成的所有八字节。 (再次假设适当的对齐)我看到B.a和B.c有5个八字节,A和A的每个字段有3个。现在规则说每个8字节被初始化为NO_CLASS。但现在要找出B级的下一步是什么?我是否参考规则5?

    2. 另一方面,另一条路径是遵循并应用规则4.我理解规则4的方式说,首先找出你的结构的每个字段的类,并通过规则4的子规则扣除类整个结构。 这里规则中有点奇怪的部分就是说

        

      根据八字节

      中字段的类别

      那里有八字节是什么意思?这是否意味着规则4仅适用于八字节对象?它不适用于任何种类的对象结构吗?它是否可能应用于规则3的结果“对象”?

    3. 最后规则5发挥作用了吗?

0 个答案:

没有答案