C语言函数调用栈的详细教程(9)
2023-04-29 来源:飞速影视
出栈(pop):栈顶指针ESP指向的栈中数据被取回到寄存器;栈顶指针ESP增加4个字节。
图6 出栈入栈操作示意
可见,压栈操作将寄存器内容存入栈内存中(寄存器原内容不变),栈顶地址减小;出栈操作从栈内存中取回寄存器内容(栈内已存数据不会自动清零),栈顶地址增大。栈顶指针ESP总是指向栈中下一个可用数据。
调用(call):将当前的指令指针EIP(该指针指向紧接在call指令后的下条指令)压入堆栈,以备返回时能恢复执行下条指令;然后设置EIP指向被调函数代码开始处,以跳转到被调函数的入口地址执行。
离开(leave): 恢复主调函数的栈帧以准备返回。等价于指令序列movl ëp, %esp(恢复原ESP值,指向被调函数栈帧开始处)和popl ëp(恢复原ebp的值,即主调函数帧基指针)。
返回(ret):与call指令配合,用于从函数或过程返回。从栈顶弹出返回地址(之前call指令保存的下条指令地址)到EIP寄存器中,程序转到该地址处继续执行(此时ESP指向进入函数时的第一个参数)。若带立即数,ESP再加立即数(丢弃一些在执行call前入栈的参数)。使用该指令前,应使当前栈顶指针所指向位置的内容正好是先前call指令保存的返回地址。
基于以上指令,使用C调用约定的被调函数典型的函数序和函数跋实现如下:
指令序列
含义
函数序
(prologue)
push ëp
将主调函数的帧基指针ëp压栈,即保存旧栈帧中的帧基指针以便函数返回时恢复旧栈帧
mov %esp, ëp
将主调函数的栈顶指针%esp赋给被调函数帧基指针ëp。此时,ëp指向被调函数新栈帧的起始地址(栈底),亦即旧ëp入栈后的栈顶
sub
将栈顶指针%esp减去指定字节数(栈顶下移),即为被调函数局部变量开辟栈空间。
本站仅为学习交流之用,所有视频和图片均来自互联网收集而来,版权归原创者所有,本网站只提供web页面服务,并不提供资源存储,也不参与录制、上传
若本站收录的节目无意侵犯了贵司版权,请发邮件(我们会在3个工作日内删除侵权内容,谢谢。)
www.fs94.org-飞速影视 粤ICP备74369512号