c语言 可变参数函数,C语言变参函数,可变参数是如何入栈的?

这个参数咋传,跟你用得编译器、操作系统,目标体系结构都有关 ... ,可以去看一下Calling Convetion简单了解一下。

对 gcc Linux x86-64 来说,开始的几个参数根本不在栈里,而是用的寄存器。

把你的函数拼了个程序,放到godbolt上看了一下:

void func(const char *fmt, ...)

{

printf("%p", &fmt);

}

int main(int argc, const char **argv) {

func("test", 1, 2, 3, 4, 5, 6, 7);

}

func 的调用是这样:

push 7

push 6

mov r9d, 5

mov r8d, 4

mov ecx, 3

mov edx, 2

mov esi, 1

mov edi, OFFSET FLAT:.LC1

mov eax, 0

call func

add rsp, 16

mov eax, 0

可以看出除了 6 跟 7 ,其他所有参数都在寄存器里。

进入 func 之后,这些参数又被从寄存器放回了内存(为了实现 va_list 等等 ...):

push rbp

mov rbp, rsp

sub rsp, 192

mov QWORD PTR [rbp-184], rdi

mov QWORD PTR [rbp-168], rsi

mov QWORD PTR [rbp-160], rdx

mov QWORD PTR [rbp-152], rcx

mov QWORD PTR [rbp-144], r8

mov QWORD PTR [rbp-136], r9

然而第一个参数跟后续的并不连续,并且参数 5 (后放进内存的)跟 参数 6 (直接压栈)也并不连续。

最后,其他的编译器/操作系统/体系结构的组合,可能完全不是这么搞的。比如 x86(32位) ,所有参数都会被压倒栈里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值