• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Delphi中的堆,栈

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

来自:http://blog.163.com/liang_liu99/blog/static/884152162009111303756371/

--------------------------------------------------------------------------------------------

Heap:堆,Heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里 
Stack:栈或堆栈,Stack上分配的内存系统自动释放

以下摘自 <<Essential Pascal>> 

Delphi 用堆的形式来给对象,字符串,动态数组,分配内存;那些有特殊用途的动态存储空间(用GetMem获取)也是用堆实现的。 

Delphi 用栈来存储参数和返回值,本地例程变量等等。对 Windows API 调用也要用到栈。 

Windows 应用程序可以保留大量的内存空间以备建栈之用。在 Delphi project 选项的 linker 页里,你可以进行这方面的设置,当然,默认的设置基本上已经可以满足要求了。如果出现了栈满的错误,这常常是因为你的某个函数一直在对自己进行递归调用的缘故,而不是因为栈太小了。

一 堆栈的概念

堆栈(Stack)是一种比较重要的线性数据结构,如果对数据结构知识不是很了解的话,我们可以把它简单的看作一维数组。但是对一维数组进行元素的插入、删除操作时,可以在任何位置进行,而对于栈来说,插入、删除操作是固定在一端进行的,这一端称为栈顶(top),另一端称为栈底(bottom),向栈中插入数据的操作称为压入(Push),从栈中删除数据称为弹出(Pop)。

 

 堆栈的存储方式

对栈中元素的操作是按后进先出(Last In First Out,简称LIFO)的原则进行的,即最后压入的元素最先弹出。

在栈的操作过程中,有一个永远指向栈顶的栈顶指针,在压入和弹出数据时,栈顶指针向上或向下移动。当栈顶指针为零时(即指向栈底的后面),栈为空栈。如果压入的数据过多超出了栈的最大空间,则发生栈上溢。

在程序设计中,我们可以使用一维数组实现对栈的操作。假设用一维数组s[1..arrmax]表示栈,则对于非空栈,s[1]为最早压入栈的元素,同时设栈顶指针top,则s[top]为最后压入栈的元素。当top=arrmax时栈满,若此时有数据入栈将产生“数组越界”的错误,极为栈上溢,反之当top =0,意为栈空。

 

三 堆栈的存储演示

 

 

有些人可能认为,我们要学习的内容是函数的递归调用知识,与堆栈有什么关系。实际上程序在执行的过程中,为了实现函数的嵌套调用都离不开栈。为什么函数在多层嵌套调用以后程序执行不会混乱?为什么函数被调用以后还能返回到原处继续执行?这都是堆栈的功劳。

8086寄存器(1)

                                      

代码段 

+-------+<--- CS 
| 指令 |
+-------+
| 指令 |
+-------+<--- IP
| 指令 |
+-------+
| …… | 
+-------+
数据段 

+-------+<--- DS 
| 数据 |
+-------+
| 数据 |
+-------+<--- SI (DI)
| 数据 |
+-------+
| …… | 
+-------+
堆栈段 

+-------+<--- SS 
| 栈帧 |
+-------+
| 栈帧 |
+-------+<--- BP
| 栈帧 |
+-------+
| …… |<--- SP 
+-------+


汇编是最底层的计算机语言,写汇编程序就是在对内存和寄存器操作。以上描述的代码段、数据段、堆栈段都是指内存中某段区域。当程序编译时,编译器会把程序中的代码分配到不同的内存区域。这时,代码段和数据段在内存中的位置和宽度都已固定好,而堆栈段只有起始位置,没有实际的内容,在运行时根据数据动态伸缩,因此,它是运行时系统很重要的一个部分。存放在内存中的(注意,指令在没有被CPU处理时,只是一串字符)都是数据。

内存有了数据,这时就要用到寄存器。所有的指令运算都要经过CPU中的运算器,而运算器并不知道要处理的数据在哪,因此,寄存器就扮演了数据定位的角色。寄存器也是CPU的一部分,它就专门在内存中找数据,然后告诉运算器做处理。这一过程,有个专门的术语叫“寻址”。

这里并不对所有的寄存器做介绍,只说明一些最常用的。图中用箭头表示的都是寄存器。这些都由CPU指定了特定的功能,不能作其它用途。CS和IP这两个寄存器只负责在代码段寻址,CS定位到了代码段,IP定位到具体的指令。原先说过,在内存中的都是数据,当IP有所指向的时候,数据变成了可以执行的程序,交付运算器执行。CS的地址由系统来指定。IP的控制权不在用户,而是CPU本身。DS和SI、DI负责数据段寻址,数据段是保存全局并赋值的数据的地方。 SI用于读数据,DI用于写数据。DS也是由系统指定,其中的数据读取有专门的寻址方法(见gas初级教程中的寻址一节和其它的实例代码)。SS由系统维护的堆栈段首地址,初始时SP、BP和SS处于同一位置。堆栈是一动态内存区域,它的伸展方向是从高地址向低地址方向延伸。因此,高地址处叫做“栈底”,低地址处叫做“栈顶”。SP是堆栈指针,始终指向栈顶,由它来负责栈的伸缩。在函数调用时,函数中的数据都在堆栈中,BP就用来限制只能读取函数内部的数据。每个函数的调用,都用一个帧框表示,通过不同的帧框来区分不同的函数,BP就在帧框中移动。

还有AX、BX、CX、DX四个通用寄存器,它们在一般情况下可任意使用。但在一些指令中会有特别说明其中的特殊用途(请查看CPU指令手册)。

本人水平有限,因为在学汇编语言时,又不得不了解寄存器的操作。这里只能抛砖引玉,作简单介绍。望各位指点。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
matlab读取nc发布时间:2022-07-18
下一篇:
matlab学习——05插值和拟合(黄河小浪底调水调沙问题)发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap