在第3.2.3节中,x86_64 System V ABI指定函数调用的哪些参数放入哪些寄存器中以及哪些被推入栈中。我对聚合体分类算法感到困惑,它说(高亮部分为我添加):
聚合类型(结构体和数组)和联合类型的分类方式如下:
1. 如果一个对象的大小大于8个8字节或者它包含不对齐的字段,则它的分类为MEMORY。 2. 如果一个C++对象在调用的目的上是非平凡的,正如C++ ABI规范中所指定的那样,则通过不可见引用传递(该对象在参数列表中被一个具有INTEGER类的指针替换)。 3. 如果聚合量的大小超过单个8字节,则每个聚合量按独立方式进行分类。每个8字节都被初始化为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) 如果聚合量的大小超过2个8字节,并且第一个8字节不是SSE,或者任何其他8字节不是SSEUP,则整个参数都通过内存传递。(d) 如果SSEUP没有前置SSE或SSEUP,则它将转换为SSE。
我不理解点(3),(4)和(5)。具体来说,我有以下问题:
Q1.在第(3)点中,“每个分别分类”是指“每个八字节”吗?如果是这样,那么我希望接下来的内容是关于八字节分类的解释。
Q2.在第(4)点中,“对象的每个字段”是指“第(3)点中分离出的每个八字节的每个字段”吗?
Q3.在第(4)点中,“总是考虑两个字段”,它们是指连续的两个字段吗?
Q4.在第(4)点中,“结果类”是指对象的类、八字节的类、第二个被考虑字段的类还是其他什么类?在最后一种情况下,结果类在哪里使用?这是否意味着算法保留第一个字段,并迭代计算下一个字段的类,直到我们得到八字节中所有字段的类?还是它意味着算法一次处理两个字段?
Q5.在第(4)点中,如果只有一个字段,或者有偶数个字段,会怎样?
聚合类型(结构体和数组)和联合类型的分类方式如下:
1. 如果一个对象的大小大于8个8字节或者它包含不对齐的字段,则它的分类为MEMORY。 2. 如果一个C++对象在调用的目的上是非平凡的,正如C++ ABI规范中所指定的那样,则通过不可见引用传递(该对象在参数列表中被一个具有INTEGER类的指针替换)。 3. 如果聚合量的大小超过单个8字节,则每个聚合量按独立方式进行分类。每个8字节都被初始化为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) 如果聚合量的大小超过2个8字节,并且第一个8字节不是SSE,或者任何其他8字节不是SSEUP,则整个参数都通过内存传递。(d) 如果SSEUP没有前置SSE或SSEUP,则它将转换为SSE。
我不理解点(3),(4)和(5)。具体来说,我有以下问题:
Q1.在第(3)点中,“每个分别分类”是指“每个八字节”吗?如果是这样,那么我希望接下来的内容是关于八字节分类的解释。
Q2.在第(4)点中,“对象的每个字段”是指“第(3)点中分离出的每个八字节的每个字段”吗?
Q3.在第(4)点中,“总是考虑两个字段”,它们是指连续的两个字段吗?
Q4.在第(4)点中,“结果类”是指对象的类、八字节的类、第二个被考虑字段的类还是其他什么类?在最后一种情况下,结果类在哪里使用?这是否意味着算法保留第一个字段,并迭代计算下一个字段的类,直到我们得到八字节中所有字段的类?还是它意味着算法一次处理两个字段?
Q5.在第(4)点中,如果只有一个字段,或者有偶数个字段,会怎样?
问题6. 在第5点中,“字段的一个类别”还是“八字节的一个类别”?
如果有人能提供更正式/精确的内容 - 例如,伪代码或流程图 - 那将是理想的。
s
是通过栈传递的,所以它在内存中,对吧?// Type your code here, or load an example. class s { public: int i; int d; int j; int k; int g; int h; }; void g(s pi, int j) { } int main() { s s1; int i = 4; g(s1, i); }
- EvanL00