图解简单C程序的运行时结构

作者: MARIOW | 来源:发表于2019-04-11 23:24 被阅读11次

程序在内存中的存储分为三个区域,分别是动态数据区、静态数据区和代码区。函数存储在代码区,全局变量以及静态变量存储在静态数据区,而在程序执行的时候才会在动态数据区产生数据。程序执行的本质就是代码区的指令不断执行,驱使动态数据区和静态数据区产生数据变化。


图解简单C程序的运行时结构

代码区与动态数据区由三个寄存器控制,分别是eip、ebp和esp。eip指向代码区下一个要执行的指令,ebp与esp分别指向动态数据区的栈底和栈顶。初始情况下eip默认指向main函数的第一条指令,esp、ebp指向的位置由程序加载时内核的设置决定。


图解简单C程序的运行时结构

我们看一下这段代码如何执行的,在执行第一条指令时,考虑到函数调用的问题,ebp会先把当前指向的地址记录到栈中,方便以后返回来继续执行。把地址压进栈时,esp就会自动往栈顶方向移动。说到这里,为避免混淆先科普一下什么是栈顶和栈底,栈只允许在一端做插入和删除操作,这一端就叫栈顶,而另一端叫做栈底,图中下方叫栈顶,上方叫栈底。esp永远在栈顶,也就是图的最下方。


图解简单C程序的运行时结构

由于esp指向的地址已经被记录,那么它就被空闲出来了。现在我们开始构建main函数的栈,空闲的esp帮忙看着main函数的栈底。这个时候esp与ebp是重叠的。


图解简单C程序的运行时结构

eip继续指向下一条指令,到了局部变量i的初始化,这里将i赋值为4,就将i的初始值压到栈中,esp继续往栈顶移动。下一条指令与本条相同,将局部变量j也压入栈中,如图所示。


图解简单C程序的运行时结构

接下来调用了fun函数,虽然fun函数是独立的函数,但是由于是在main函数中调用的,所以依然将数据压至main函数的栈中。fun函数的传入参数为i、j,但是入栈的顺序正好相反,b先入栈,然后a被压入栈中,如图所示。


图解简单C程序的运行时结构

接下来要跳转到fun函数了,在跳转之前,我们要先给fun函数的返回值留个位置,因为要赋值给局部变量m的。然后再将fun函数的返回地址压入栈中,方便执行完fun函数后能继续往下执行。最后再把ebp当前的地址值压入栈中,此时ebp指向的是main函数的栈底(如果这里不做保存,fun函数执行完ebp就回不去了)。


图解简单C程序的运行时结构

接下来就正式进入了fun函数,像第一次保存完地址值那样,ebp又被闲置了,所以让ebp守住fun函数的栈底。而局部变量b与c的赋值就不再多说,与main函数的执行过程相同,当走到了return时,将计算出的结果赋值写入到刚空出的返回值那里。


图解简单C程序的运行时结构

此时的fun函数就执行完毕了,我们要恢复main函数调用fun函数的现场,继续往下执行,要想往下执行,必须将ebp回到main函数的栈底,并且找到fun函数返回的位置,然后跳转到那里。很简单,由于刚才保存了ebp的地址值,所以将地址值赋值给ebp,ebp就指向了main函数的栈底。


图解简单C程序的运行时结构

ebp的地址值出栈后,esp就指向了fun函数的返回地址,通过执行ret指令,把该地址值传给eip,使eip指向fun函数执行后的返回地址。


图解简单C程序的运行时结构

这样就恢复了现场,然后把fun函数的返回值传递给m,此时局部变量b、a和返回值已经没有价值了,把它们清出栈,现在就剩下干干净净的栈内容了。


图解简单C程序的运行时结构

现在执行最后一步,main函数就结束了,此时局部变量i、j也没有任何作用,做清栈操作,清理出干净的栈空间。


图解简单C程序的运行时结构

以上便是一个简单C程序的运行时结构。本文总结于新设计团队的《编译系统透视:图解编译原理》,图侵删。

相关文章

  • 图解简单C程序的运行时结构

    程序在内存中的存储分为三个区域,分别是动态数据区、静态数据区和代码区。函数存储在代码区,全局变量以及静态变量存储在...

  • Cocoa 消息机制 (Objective-C 反射相关)

    Cocoa 消息机制 (Objective-C 反射相关) 相关概念 动态语言 程序运行时,允许改变程序结构或变量...

  • Java的动态机制---反射

    反射机制 动态语言,程序运行时可改变程序结构或变量类型Python、ruby。运行时可以动态的改变结构。利用反射机...

  • c#特性

    c#特性: 特性(Attribute)是用于在运行时传递程序中的各种元素(比如类,方法,结构,枚举,组件等)的行为...

  • JinLou-C++day03

    程序流程结构 C/C++⽀持最基本的三种程序运⾏结构:顺序结构、选择结构、循环结构 顺序结构:程序按顺序执⾏,不发...

  • C语言基础知识

    •1 C语言程序的结构认识 用一个简单的c程序例子,介绍c语言的基本构成、格式、以及良好的书写风格,使读者对c语...

  • Java反射

    反射作用 1、反射获取程序在运行时刻的内部结构 2、在运行时刻对一个Java对象进行操作 反射方法介绍 1、获取C...

  • C#类型

    《C#图解教程》学习记录 C#程序是一组类型声明。类型是一种用来创建数据结构的模板。 预定义类型 C#提供了16种...

  • C# 中的栈和堆

    本文是《C# 图解教程》的笔记。 程序运行时,它的数据必须存储在内存中。一个数据项需要多大的内存、存储在什么地方、...

  • C语言零基础入门难发愁,那就快来看看这篇基础整理资料吧

    C语言程序的结构认识 用一个简单的c程序例子,介绍c语言的基本构成、格式、以及良好的书写风格,使小伙伴对c语言有个...

网友评论

    本文标题:图解简单C程序的运行时结构

    本文链接:https://www.haomeiwen.com/subject/pbvfwqtx.html