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

Assembly System V AMD64结构类型参数调用约定,assembly,struct,x86-64,calling-convention,Assembly,Struct,X86 64,Calling Convention,我正在阅读有关SystemV AMD64调用约定的内容。它有一个部分,它在类中对函数的参数进行分类,其中一些是INTEGER、SSE、SSEUP、NO_类、MEMORY等 我很难理解它如何分类聚合类型,即结构、联合和数组。以下是这些分类所遵循的规则 规则: 如果一个对象的大小大于八个八字节,或者它包含未对齐的字段,则它具有类内存 > C++对象有非平凡的拷贝构造函数或非平凡的析构函数,它是通过不可见的引用传递的(对象在参数列表中被一个具有类整数的指针替换)。 如果骨料的尺寸超过一个八字节,则

我正在阅读有关SystemV AMD64调用约定的内容。它有一个部分,它在类中对函数的参数进行分类,其中一些是INTEGER、SSE、SSEUP、NO_类、MEMORY等

我很难理解它如何分类聚合类型,即结构、联合和数组。以下是这些分类所遵循的规则


规则:

  • 如果一个对象的大小大于八个八字节,或者它包含未对齐的字段,则它具有类内存

  • <> > C++对象有非平凡的拷贝构造函数或非平凡的析构函数,它是通过不可见的引用传递的(对象在参数列表中被一个具有类整数的指针替换)。
  • 如果骨料的尺寸超过一个八字节,则每个八字节单独分类。每个八字节初始化为类NO\u类

  • 对象的每个字段都被递归地分类,以便始终考虑两个字段。根据八字节中字段的类别计算得到的类别:

    • (a) 如果两个类相等,则这是结果类
    • (b) 如果其中一个类是NO_类,则生成的类是另一个类 班级
    • (c) 如果其中一个类是MEMORY,那么结果就是MEMORY类
    • (d) 如果其中一个类为整数,则结果为整数
    • (e) 如果其中一个类是X87、X87UP、COMPLEX_X87类,则将内存用作类
    • (f) 否则使用SSE类
  • 然后进行合并后清理:

    • (a) 如果其中一个类是MEMORY,则传入整个参数 记忆
    • (b) 如果X87UP前面没有X87,则传入整个参数 记忆
    • (c) 如果骨料的大小超过两个八字节,且前八个字节- 字节不是SSE或任何其他八字节不是SSEUP,整个参数 在内存中传递
    • (d) 如果SSEUP前面没有SSE或SSEUP,则将其转换为SSE

  • 我的问题是理解规则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都可以应用。因此,有两条途径:

  • 第一条道路是遵循规则3。规则3可以应用于
    sizeof(B)>8
    ,因此它告诉我将B对象分解为它所包含的所有八个字节。(再次假设正确对齐)我看到5个八字节,2个用于B.a和B.c,3个用于a的每个字段。现在规则说每个八字节都被初始化为NO_类。但是下一步是什么来找出B类呢?我是否参考第5条

  • 另一方面,另一条道路是遵循并应用规则4。按照我对规则4的理解,首先找出结构中每个字段的类,然后通过规则4的子规则扣除整个结构的类。但对我来说,规则中有点奇怪的部分是当它说

    根据八字节中字段的类别

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


  • 最后,规则5在哪里起作用?

    这是一大堆需要说明的案例。也许你可以自己举个例子,看看你是否正确地应用了规则。你也可以使用编译器进行验证。我理解并且同意你的观点,但是我完全无法理解这3点。例如,第三条规则告诉我,在构成它的所有八个字节中,完全分解每个大小>8字节的对象,并分别对它们进行分类,但这在我们应用规则4之后适用吗?第4条规则“始终考虑两个字段”是什么意思?哪两个?@Jester我也不关心规则4和5的每一部分,例如忽略SSE[UP],X87[UP],复合体就可以了,我只想知道大概的意思。
    哪两个
    :它递归地说,所以你选择前两个,对它进行分类,然后选择结果,然后选择下一个,等等。显然,规则4在规则3之后。至少发布一个你想要解释的例子。通常可以安全地假设编译器正确地实现了它。因此,如果你不确定如何解释某件事,那么想想一个实验,它会对不同的可能解释产生不同的结果。制作测试函数以查看gcc和clang将传出参数放在何处/查找传入参数。这是有用的。