c参数的生存周期的疑问
我知道c语言中每个函数在调用过程中都存在一个调用栈帧,
如下所示:
第一个参数
----------------
第二个参数
-----------------
. . . .
---------------
返回地址
--------------
pushl %ebp
movl %esp, %ebp
. . .
..........
movl %ebp, %esp
popl %ebp
ret
从上面的过程可以得出以下2点:
1) 函数的局部变量在 movl %ebp, %esp 之后就消亡了。
2) ret指令的作用是将esp指针所指向的内容弹出到eip中从而实现函数的返回,也就说esp指针现在是指向最后入栈的
那个参数的。
这里就产生了问题
若第二点是正确的,也就说函数的参数没有随着函数调用的结束而消亡,反而继续存在栈中。试想如果函数调用很多(这里不是说在函数的嵌套调用),
那么这些函数的参数都留在栈中,是否会存在这种情况:进程的整个地址空间都被函数的参数占据,导致程序崩溃。或者说函数的调用次数是有限制的。
进一步讲,在linux内核中,在内核空间运行的程序只有两页大小的内核栈,这种情况带来的危险岂不是更严重?
不知道我上面的分析对不对,望高手给出解答
如下所示:
第一个参数
----------------
第二个参数
-----------------
. . . .
---------------
返回地址
--------------
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 //在这里清空参数栈
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这种形式
pushl %ebp
movl %esp, %ebp
. . .
..........
movl %ebp, %esp
popl %ebp
ret
没有见过 ret N这种形式
作者: bigfeng12 发布时间: 2011-01-08
回复 bigfeng12
linux下面应该用第二种方法较多。
当年写8086的汇编的时候,我们都用第一种方法清除参数
linux下面应该用第二种方法较多。
当年写8086的汇编的时候,我们都用第一种方法清除参数
作者: cluter 发布时间: 2011-01-08