Assembly 根据SysV ABI对由3个“unsigned int”组成的结构进行分类

Assembly 根据SysV ABI对由3个“unsigned int”组成的结构进行分类,assembly,x86,language-lawyer,x86-64,abi,Assembly,X86,Language Lawyer,X86 64,Abi,我正在尝试对以下结构进行分类: struct test{ unsigned a; unsigned b; unsigned c; }; 据 考虑到以下职能: struct test get_test(void){ return (struct test){10, 20, 30}; } 我们有以下编译代码: Dump of assembler code for function get_test: 0x0000000000000860 <+0>

我正在尝试对以下结构进行分类:

struct test{
    unsigned a;
    unsigned b;
    unsigned c;
};


考虑到以下职能:

struct test get_test(void){
    return (struct test){10, 20, 30};
}
我们有以下编译代码:

Dump of assembler code for function get_test:
   0x0000000000000860 <+0>:     movabs rax,0x140000000a
   0x000000000000086a <+10>:    mov    edx,0x1e
   0x000000000000086f <+15>:    ret    
End of assembler dump.
函数get\u测试的汇编程序代码转储: 0x0000000000000860:movabs rax,0x14000000A 0x000000000000086a:mov edx,0x1e 0x000000000000086f:ret 汇编程序转储结束。 这表明整个
结构测试
被归类为
整数
,并在
rax
/
rdx
中返回。但原因尚不清楚

结构测试的分类从对其八个字节的每个字节进行分类开始

如果骨料的大小超过一个八字节,则每个八字节 单独分类。每个八字节初始化为类
NO_CLASS

八个字节中的每一个都被分类为
整数
AMD64 ABI/3.2.3

4.对对象的每个字段进行递归分类,以便始终有两个 字段被考虑。生成的类是根据 对于八字节中的字段类:

[……]

(d) 如果其中一个类为整数,则结果为整数

[……]


问题:使用什么规则对整个此类结构进行分类

我在这里找不到合适的
AMD64 ABI/3.2.3

5.然后进行合并后清理:

(a) 如果其中一个类是MEMORY,则整个参数将在内存中传递

(b) 如果X87UP不是 前面是X87,整个参数在内存中传递

(c) 如果 聚合的大小超过两个八字节和前八个字节 是不是SSE或任何其他八字节都不是SSEUP,整个论点是 在内存中传递

(d) 如果SSEUP前面没有SSE或SSEUP,则为 转换为苏格兰和南方能源公司


结构的八个字节既不是
内存
也不是
SSE
也不是
X87
也不是整个结构超过两个八个字节。

如果
If
s不匹配,则后期合并是不可操作的。对我来说,这似乎是一个简单的分类:(INT+INT)+INT=INT因此使用了
rdx:rax
@MargaretBloom,因此4号项目符号与对每个eigthbyte(不仅仅是一个字段)进行分类以及对整个聚合进行分类(合并聚合的每个八字节)有关?如果是这样的话,从
4.
的措辞来看,这一点并不十分清楚。每个八字节(8B)都是单独分类的,8B中最多可以有8个字段。8B的类别最初设置为8B中第一个字段的类别,然后将当前类别和8B中下一个尚未分析的字段的类别一起考虑,以形成新的8B类别(根据第4点)。重复此步骤,直到8B中的所有字段都已分析完毕。重复此步骤,直到所有8B都已分类。进行后期合并(第5点)。看看这个有趣的例子。现在,只剩下跨越两个8B的字段。。。。。。但在IIRC的某个地方有一个对齐检查。我还没有完全解开这个算法,如果我需要返回一个结构,我仍然会检查编译器。我相信只要有一点耐心和一些测试,就可以完全理解算法。我只是从来没有必要:)@MargaretBloom重复,直到所有的8位都被分类。因此,我们对所有的8b进行了分类,在我的示例中,我们有两个
INT
s,但我们没有在这一点上对整个结构进行分类。因为post merge是no op,所以整个结构是根据
4简单地合并8b来分类的。