操作系统堆栈

      在学习了关于系统堆栈的一些原理后,发表一下自己的看法与理解,希望能帮助到其他人。

堆栈的简介  :堆栈是一个在计算机科学中经常使用的抽象数据类型。堆栈中的物体具有一个特性: 最后一个放入堆栈中的物体总是被最先拿出来, 这个特性通常称为后进先出队列。 堆栈中定义了一些操作。 两个最重要的是PUSH和POP。 PUSH操作在堆栈的顶部加入一个元素。POP操作相反, 在堆栈顶部移去一个元素, 并将堆栈的大小减一。给个简图理解下:先进后出队列:堆栈好比这个容器放入时是先放入1其次2然后3,当要取出时,只能先取出3其次2然后1.

计算机内存空间:一般内存空间的开头部分与结尾部分。被操作系统用。其他部分即可用空间,大概分为堆空间,栈空间,代码区等

*栈: 用户维护函数调用上下文。由高地址向低地址生长,通常以M为单位,由操作系统维护。

  [不能申请占用过大的内存的局部变量,会导致栈爆掉而core.如果变量太大,可以考虑放到全局变量区或者使用堆]

*堆: 动态申请内存,即使用new or malloc等分配到的内存,可以比栈大很多,需用户自己释放

  [new/delete,malloc/free成对出现,否则会导致内存泄露,可以使用查找内存泄露的工具监控或者自己写代码监控]

*代码区:存放代码的内存映像

堆栈分配及原理:

堆:用于动态分配内存,c语言中使用malloc/free进行申请和释放。申请空间这种事一般都是有操作系统来做,但是在编程是我们需要经常申请空间,就需要经常调用系统代码。在用户状态与内核态之间切换,也就是频繁的调用中断处理程序,导致性能较差,但事实上不是这样的,比如在写c语言代码时,都是通过调运运行库封装好的库函数,而库函数里提前申请好一段适当大的内存,给编程用,当我们需要申请空间时,对于小空间直接向库函数里取相应大小的空间即可,这样就提高了性能。

栈: 栈在程序运行中的作用非常重要,它保存了一个 函数调用所需要维护的信息,称为现场保护,当函数调用结束后需要返回主函数,这时候就需要现场信息,要保护的现场信息包括(如图)

         1. 函数的返回地址,参数

         2. 临时变量

        3. 上下文:寄存器

ebp :是栈低指针,esp是栈顶指针,

1 当主函数里执行调运函数时先将把参数按照从右至左的顺序压栈,比如changenumber(num1,num2);

    先将num2入栈再将num1入栈,此顺序十分重要,以后我会举例说明其重要性。

2 将主函数当前指令的下一条指令入栈,即为保存被调函数执行结束后要执行的下一条指令。

3开始执行被调函数,先保存旧地址old ebp,和寄存器里的重要数据。局部变量:将

num1,num2的值复制一份保存在被调函数里的空间,其空间顺序为num1,num2其次看图

所以这里主函数的num1值对应着被调函数的num1的值,主函数num2对应着被调函数的num2值。具体例子我会在发表一篇博客

4当被调函数执行结束后,把old ebp读回寄存器,然后从return address开始执行。

那么,函数的返回值是如何传递的呢?

       答案:通过eax寄存器。函数将返回值存储在eax中,然后调用方读取eax。但是,eax本身只有4个字节,大于4个字节的返回值,则是通过eax存储了一个指针,而实际内容在栈上的其他地方。初学具体我也不是很清楚,望见谅.


注:此篇文章参考了百度百科,魏加恩的博客,还有一些文献。初学者,深度不够日后再补充。



猜你喜欢

转载自blog.csdn.net/qq_42034205/article/details/80376177