c参数的生存周期的疑问

我知道c语言中每个函数在调用过程中都存在一个调用栈帧,

如下所示:
  

            第一个参数
          ----------------
           第二个参数
         -----------------
               . . .  .
          ---------------
          返回地址
          --------------
         pushl   %ebp
         movl     %esp, %ebp
           .  .    .   
           ..........
         movl    %ebp, %esp
         popl    %ebp
         ret

从上面的过程可以得出以下2点:

  1)   函数的局部变量在    movl    %ebp, %esp   之后就消亡了。


   2)  ret指令的作用是将esp指针所指向的内容弹出到eip中从而实现函数的返回,也就说esp指针现在是指向最后入栈的

          那个参数的。


这里就产生了问题
      
      若第二点是正确的,也就说函数的参数没有随着函数调用的结束而消亡,反而继续存在栈中。试想如果函数调用很多(这里不是说在函数的嵌套调用),

     那么这些函数的参数都留在栈中,是否会存在这种情况:进程的整个地址空间都被函数的参数占据,导致程序崩溃。或者说函数的调用次数是有限制的。

     进一步讲,在linux内核中,在内核空间运行的程序只有两页大小的内核栈,这种情况带来的危险岂不是更严重?
      


    不知道我上面的分析对不对,望高手给出解答

作者: bigfeng12   发布时间: 2011-01-08

回复 bigfeng12


    ret N   N是弹出的字节数  所以用这种方法完全可以清空参数列表。

当然还有一种方法,就是

  push  arg1
  push  arg2
  call    func1
  sub   esp,8  //在这里清空参数栈

作者: cluter   发布时间: 2011-01-08

编译器反汇编后每个函数的形式都是:
  
         pushl   %ebp
         movl     %esp, %ebp
           .  .    .   
           ..........
         movl    %ebp, %esp
         popl    %ebp
         ret

没有见过 ret N这种形式

作者: bigfeng12   发布时间: 2011-01-08

回复 bigfeng12


linux下面应该用第二种方法较多。
当年写8086的汇编的时候,我们都用第一种方法清除参数

作者: cluter   发布时间: 2011-01-08