我想知道当我们在amd64上调用C中的libc函数时如何传递参数。
例如,如果我调用sqrt(double)
,那么参数是由堆栈还是寄存器传递的?
答案 0 :(得分:2)
我最近创建了a tool来可视化功能的堆栈帧,注册用法,结构化类型的内存布局和其他ABI信息。您可以在x86_64 here上查看libssh库函数ssh_channel_read_timeout的结果。
答案 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 的参数。