【发布时间】:2021-09-09 01:06:12
【问题描述】:
我想知道一个结构是如何返回的:
typedef struct number {
uint64_t a, b, c, d;
}number;
number get_number(){
number res = {0,0,0,0};
return res;
}
反汇编成
0000000000001149 <get_number>:
1149: 55 push rbp
114a: 48 89 e5 mov rbp,rsp
114d: 48 89 7d d8 mov QWORD PTR [rbp-0x28],rdi
1151: 48 c7 45 e0 00 00 00 mov QWORD PTR [rbp-0x20],0x0
1158: 00
1159: 48 c7 45 e8 00 00 00 mov QWORD PTR [rbp-0x18],0x0
1160: 00
1161: 48 c7 45 f0 00 00 00 mov QWORD PTR [rbp-0x10],0x0
1168: 00
1169: 48 c7 45 f8 00 00 00 mov QWORD PTR [rbp-0x8],0x0
1170: 00
1171: 48 8b 4d d8 mov rcx,QWORD PTR [rbp-0x28]
1175: 48 8b 45 e0 mov rax,QWORD PTR [rbp-0x20]
1179: 48 8b 55 e8 mov rdx,QWORD PTR [rbp-0x18]
117d: 48 89 01 mov QWORD PTR [rcx],rax
1180: 48 89 51 08 mov QWORD PTR [rcx+0x8],rdx
1184: 48 8b 45 f0 mov rax,QWORD PTR [rbp-0x10]
1188: 48 8b 55 f8 mov rdx,QWORD PTR [rbp-0x8]
118c: 48 89 41 10 mov QWORD PTR [rcx+0x10],rax
1190: 48 89 51 18 mov QWORD PTR [rcx+0x18],rdx
1194: 48 8b 45 d8 mov rax,QWORD PTR [rbp-0x28]
1198: 5d pop rbp
1199: c3 ret
从反汇编来看,在调用函数之前,所需的空间已在堆栈上分配,函数会填充这些值。
但在第二部分中,rdi 似乎被视为指向 number 结构的指针,其中的值也被保存。这是关于什么的?
当在汇编程序中使用 C 函数时,我如何知道结果在哪里?
【问题讨论】:
-
您可以在this question找到一些信息。
-
参考您平台的ABI文档。对你来说,这似乎是 amd64 SysV ABI 的补充。
-
@jaklh 使用
-O0你告诉编译器关闭它的大脑并生成尽可能愚蠢的代码。在这种情况下,你为什么期望有好的代码? -
该代码比必要的更难遵循,因为您禁用了优化。通过优化,您只会看到存储到返回值对象中,而不是初始化本地
res。 (这就是 this 函数在堆栈上分配的空间。)godbolt.org/z/M79b6zqrP : gcc -O3 使用两个 SSE2 存储,gcc -O2 使用四个直接为 0 的 qword 存储。 -
请注意,x86-64 System V 有据可查,Where is the x86-64 System V ABI documented?。在 RDX:RAX 或仅 RAX 中返回较小的结构(适合 16 个字节或更少)。 C++ on x86-64: when are structs/classes passed and returned in registers?
标签: c assembly x86-64 calling-convention