C语言函数调用过程中的内存变化解析.docxVIP

  • 10
  • 0
  • 约1.31千字
  • 约 3页
  • 2022-03-01 发布于浙江
  • 举报

C语言函数调用过程中的内存变化解析.docx

PAGE PAGE 1 C语言函数调用过程中的内存变化解析 以下代码即是此次探讨 C 语言函数调用过程的实例源码: intsubFunc(intabc){intdef=0x9999;abc=0x8888;returnabc;}int_tm(ai)n(){subFunc(0x2222);return0;} 源码很简洁,在一个主函数中,调用一个带参数的子函数。源码使用 Visual Studio2021 进行调试,并同时查看内存窗口、反汇编窗口及变量窗口。 进入调试模式,并将断点定在调用子函数 subFunc()处,然后运行并观看。 通过观看窗口,可以知道,此时还是在执行 main 函数,而 ebp(栈帧基址指针)指向的是 0x0073fb64,esp=0x0073fa98。从反汇编代码可以看到,在调用函数前,需要先将参数压栈,也就是将实参存到了 0x0073fa94 处,然后再调用到子函数。 进入到子函数时,esp 已经变成了 0x0073fa8c,而 0x0073fa90 处存放的是,子函数执行完后返回到 main 函数中的地址。进入到子函数后,先将 main 函数的 ebp 压栈,然后将当前栈顶指针的值赋值给 ebp 作为当前子函数的 subFunc()的栈帧基址指针。此时 esp 和 ebp 都变成了 0x0073fa8c。 紧接着,可以看到,esp 一下子被减去了 0x0cch,也就是说栈空间一下子增长了 0x0cch,并且这段空间全部被赋值为 0xcc。再往下看,可以看到子函数中的局部变量被安排在了 0x0073fa84 处(由于变量是 32 位的,然后 (CPU) 却是 64 位的,所以空了 32 位不作使用),也就是说,这一段被初始化为 0xcc 的栈空间是被用来给局部变量安排空间的。 接下来再看,在 main 函数传递了一个实参 0x2222 给子函数 subFunc 中的形参 abc。在对 abc 进行读写时,其实就是在对前面实参所被存储的空间进行读写,也就是说形参在作为参数也作为局部变量的同时,它所被安排的内存空间是在函数栈帧基址 ebp 之下。 而子函数被执行完后,返回的过程则是一个与上面过程相逆的过程。将相应的数据出栈,恢复 ebp 等信息,释放子函数的栈空间,返回到主函数。所以局部变量的作用域只是在函数中,当函数被执行完返回时,函数的栈帧都被释放了,局部变量等数据也就没有了,不存在了,也就是说局部变量的生命周期是与函数的生命周期等同的。 经过以上的 C 语言函数调用过程图解,信任已经理解了 C 语言在内存中是如何调用的了。然后可以总结并得出下面的函数调用的栈帧图解。从函数调用的层面看,栈空间是被从下往上一块一块地增长的,并且是后安排的先被释放,先安排的后被释放。 hfy !--

文档评论(0)

1亿VIP精品文档

相关文档