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

Purpose of rdi register for no argument function

考虑这个简单的函数:

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 创建了 space,并将 rdi 中的信息传递给了被调用者。

我正在尝试查找此约定的文档。 Calling convention in linux 声明 rdi 包含第一个整数参数。在这种情况下,foo 没有任何参数。

此外,如果我让 foo 接受一个整数参数,它现在作为 rsi(第二个参数的寄存器)传递,rdi 用于 return 对象的地址。

任何人都可以提供一些文档并阐明如何在系统 V ABI 中使用 rdi 吗?

请参阅 ABI docs 中的 3.2.3 参数传递 部分,其中指出:

If the type has class MEMORY, then the caller provides space for the return value and passes the address of this storage in %rdi as if it were the first argument to the function. In effect, this address becomes a "hidden" first argument.

On return %rax will contain the address that has been passed in by the caller in %rdi.