C语言中变长参数表printf的实现和参数入栈次序之间的关系

来源:互联网 发布:mac 连不上wifi 编辑:程序博客网 时间:2024/05/16 06:14

“C语言的从右到左入栈的特性使其可以实现如printf之类的变长参数函数”

  这是个命题,而且是个真命题。晚上查阅了一些资料,先总结如下:

(1)变长参数列表和固定参数的区别:

      我们写的大部分函数都是固定参数函数(至少我没有写过变长参数函数),编译之后,形参的地址是固定的,而且被调用函数也知道形参的地址,所以可以正确取值。比如int func(int a,int b)

(2)printf() 变长参数如何取值的?

     printf函数原型中,第一个参数是不变的,一定是一个格式字符串,后面参数的个数和内容取决于第一个参数的内容,所以又称为变长参数。在printf的实现中,不难看出,被调用函数只有在取到第一个参数后,才能确定后面参数类型和个数,所以编译器务必要把第一参数房子一个固定的位置。这个位置就是%ebp+8

 

 堆栈布局示意图

 当调用func函数后,%ebp,%esp寄存器所指向的内存单元如图所示,那么%ebp+8 指向的就是第一个形参&arg1.(在printf函数中就是格式字符串),如果按照从左往右压栈,第一个参数就不是在栈顶,而是在栈底,也就无法知道它的具体的位置了。

 

 总之:C语言中规定函数压栈的顺序为从右到左,使得第一参数总是在调用函数的栈顶,被调用函数总可以正确取到它,从而继续取其他的参数。

原创粉丝点击