rdi寄存器用于无参数功能的目的

问题描述 投票:1回答:1

考虑这个简单的功能:

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中传递给了被调用方。

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

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

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

c++ assembly x86-64 calling-convention abi
1个回答
4
投票

请参见ABI docs中的3.2.3参数传递]部分,其中:

如果类型的类别为MEMORY,则调用方为返回值,并以%rdi的形式传递此存储的地址,就好像它是该函数的第一个参数。实际上,这个地址成为“隐藏”的第一个参数。

返回时,%rax将包含由%rdi中的呼叫者。

© www.soinside.com 2019 - 2024. All rights reserved.