考虑这个简单的函数:
struct Foo {
int a;
int b;
int c;
int d;
int e;
int f;
};
Foo foo() {
Foo f;
f.a = 1;
f.b = 2;
f.c = 3;
f.d = 4;
f.e = 5;
f.f = 6;
return f;
}
它生成以下程序集:
0000000000400500 <foo()>:
400500: 48 ba 01 00 00 00 02 movabs rdx,0x200000001
400507: 00 00 00
40050a: 48 b9 03 00 00 00 04 movabs rcx,0x400000003
400511: 00 00 00
400514: 48 be 05 00 00 00 06 movabs rsi,0x600000005
40051b: 00 00 00
40051e: 48 89 17 mov QWORD PTR [rdi],rdx
400521: 48 89 4f 08 mov QWORD PTR [rdi+0x8],rcx
400525: 48 89 77 10 mov QWORD PTR [rdi+0x10],rsi
400529: 48 89 f8 mov rax,rdi
40052c: c3 ret
40052d: 0f 1f 00 nop DWORD PTR [rax]
根据程序集,我了解到调用者为Foo
在其堆栈上,并将该信息传递给rdi
给被叫方。
我正在尝试查找该约定的文档。Linux中的调用约定 https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI指出rdi
包含第一个整数参数。在这种情况下,foo
没有任何论据。
此外,如果我做foo
采用一个整数参数,现在传递为rsi
(注册第二个参数),rdi 用于返回对象的地址。
任何人都可以提供一些文档并说明如何进行rdi
用于系统V ABI?
参见部分3.2.3 参数传递 in the ABI docs https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf其中说:
如果该类型具有 MEMORY 类,则调用者为该类型提供空间
返回值并在 %rdi 中传递此存储的地址,就好像它一样
是函数的第一个参数。实际上,这个地址
成为“隐藏”的第一个参数。
返回时 %rax 将包含由 %rax 传入的地址
%rdi 中的调用者。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)