如何在amd64中传递参数?

时间:2014-05-05 16:18:09

标签: gcc x86-64 abi

我想知道当我们在amd64上调用C中的libc函数时如何传递参数。

例如,如果我调用sqrt(double),那么参数是由堆栈还是寄存器传递的?

2 个答案:

答案 0 :(得分:2)

我最近创建了a tool来可视化功能的堆栈帧,注册用法,结构化类型的内存布局和其他ABI信息。您可以在x86_64 here上查看libssh库函数ssh_channel_read_timeout的结果。

enter image description here enter image description here

答案 1 :(得分:1)

让我们编写一个示例用例( test.c ):

#include <math.h>

int main()
{
    double val = sqrt(foo(8));
    return 0;
}

double foo(double val)
{
    val+=1;
    return val;
}

编译:

gcc test.c -lm

然后检查导入的符号:

readelf -Wa a.out |grep sqrt

    4: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND sqrt@GLIBC_2.2.5 (3)
   63: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND sqrt@@GLIBC_2.2.5

反汇编对象:

objdump -d a.out

0000000000400582 <main>:
  400582:       55                      push   %rbp
  400583:       48 89 e5                mov    %rsp,%rbp
  400586:       48 83 ec 10             sub    $0x10,%rsp
  40058a:       f2 0f 10 05 26 01 00    movsd  0x126(%rip),%xmm0
  400591:       00 
  400592:       e8 bd ff ff ff          callq  400554 <foo>
  400597:       66 0f 28 c8             movapd %xmm0,%xmm1
  40059b:       f2 0f 51 c1             sqrtsd %xmm1,%xmm0
  40059f:       66 0f 2e c0             ucomisd %xmm0,%xmm0
  4005a3:       7a 06                   jp     4005ab <main+0x29>
  4005a5:       66 0f 2e c0             ucomisd %xmm0,%xmm0
  4005a9:       74 09                   je     4005b4 <main+0x32>
  4005ab:       66 0f 28 c1             movapd %xmm1,%xmm0
  4005af:       e8 ac fe ff ff          callq  400460 <sqrt@plt>
  4005b4:       f2 0f 11 45 f8          movsd  %xmm0,-0x8(%rbp)
  4005b9:       b8 00 00 00 00          mov    $0x0,%eax
  4005be:       c9                      leaveq 
  4005bf:       c3                      retq

因此,您可以看到%xmm0 寄存器传递 sqrt 的参数。