rdi 寄存器用于无参数函数的目的

skg*_*nga 2 c++ assembly x86-64 abi calling-convention

考虑这个简单的函数:

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;
}
Run Code Online (Sandbox Code Playgroud)

它生成以下程序集:

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]

Run Code Online (Sandbox Code Playgroud)

根据程序集,我知道调用者Foo在其堆栈上创建了空间,并将该信息传递rdi给被调用者。

我正在尝试查找此约定的文档。调用在linux惯例,各国rdi包含第一个整型参数。在这种情况下,foo没有任何参数。

此外,如果我foo使用一个整数参数,它现在作为rsi(注册第二个参数)传递,rdi 用于返回对象的地址。

任何人都可以提供一些有关如何rdi在系统 V ABI 中使用的文档和说明吗?

Jes*_*ter 7

请参阅ABI 文档中的第3.2.3参数传递,其中说:

如果类型具有类 MEMORY,则调用者为返回值提供空间并在 %rdi 中传递此存储的地址,就好像它是函数的第一个参数一样。实际上,这个地址变成了“隐藏的”第一个参数。

返回时 %rax 将包含调用者在 %rdi 中传入的地址。