来自: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指令手册)。

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

Delphi中的堆,栈的更多相关文章

  1. Delphi中堆栈区别

     http://blog.csdn.net/zang141588761/article/details/52838728 Delphi中堆栈区别 2016-10-17 14:49 277人阅读 评论( ...

  2. (十一)C语言中内存堆和栈的区别

    在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到.但对于很多的初学着来说,堆栈是一个很模糊的概念. 堆栈:一种数据结构.一个在程序运行时用于存放的地方,这可能是很多初学者的认 ...

  3. C语言中的堆与栈20160604

    首先声明这里说的是C语言中的堆与栈,并不是数据结构中的!一.前言介绍:C语言程序经过编译连接后形成编译.连接后形成的二进制映像文件是静态区域由代码段和数据段(由二部分部分组成:只读数据 段,未初始化数 ...

  4. Java中的堆和栈的区别

    当一个人开始学习Java或者其他编程语言的时候,会接触到堆和栈,由于一开始没有明确清晰的说明解释,很多人会产生很多疑问,什么是堆,什么是栈,堆和栈有什么区别?更糟糕的是,Java中存在栈这样一个后进先 ...

  5. iOS中的堆(heap)和栈(stack)的理解

    操作系统iOS 中应用程序使用的计算机内存不是统一分配空间,运行代码使用的空间在三个不同的内存区域,分成三个段:“text segment “,“stack segment ”,“heap segme ...

  6. Java中的堆内存、栈内存、静态存储区

    一.栈 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用.但缺点是,存在栈中的数据大小与生存 ...

  7. 深入浅出C语言中的堆和栈

    在谈堆栈的时候,我在这有必要把计算机的内存结构给大家简单的介绍下(高手们可以直接飘过) 一. 内存结构   每个程序一启动都有一个大小为4GB的内存,这个内存叫虚拟内存,是概念上的,真正能用到的,只是 ...

  8. java中的堆、栈、常量池

    java中的堆.栈.常量池 分类: java2010-01-15 03:03 4248人阅读 评论(5) 收藏 举报 javastring编译器jvm存储equals Java内存分配: 1. 寄存器 ...

  9. (转)认识java中的堆和栈

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆.      Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new. ...

随机推荐

  1. Servlet过滤器---简介

    过滤器的基本概念 Servlet过滤器从字面上的字意理解为经过一层次的过滤处理才达到使用的要求,而其实Servlet过滤器就是服务器与客户端请求与响应的中间层组件,在实际项目开发中Servlet过滤器 ...

  2. HDU 1384 Intervals(差分约束)

    Intervals Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  3. Hyper-V在线调整虚拟硬盘大小

    从Windows Server 2012 R2 开始,可以在线调整虚拟硬盘的大小了,这意味着当虚拟硬盘不够用时,我们在虚拟机运行的情况下直接扩展虚拟硬盘容量了.有人说这个有什么用?当然,实验室情况下, ...

  4. 《Cracking the Coding Interview》——第16章:线程与锁——题目5

    2014-04-27 20:16 题目:假设一个类Foo有三个公有的成员方法first().second().third().请用锁的方法来控制调用行为,使得他们的执行循序总是遵从first.seco ...

  5. python学习笔记四:lambda表达式和switch

    一.定义 lambda arg1,arg2... : returnValue 二.示例 #!/usr/bin/python def f(x,y): return x*y print f(2,3) g ...

  6. 常用模块(datatime)

    import datetime,time# dt = datetime.datetime.now() # 获取当前时间的时间对象# dt = datetime.date.fromtimestamp(t ...

  7. ipa和ironic-conductor交互

    IPA使用lookup和hearteat机制与Ironic Conductor进行交互,启动时agent给Conductor的vendor_passthru lookup endpoint(地址为/v ...

  8. A. Vasya and Book

    题目原址 http://codeforces.com/contest/1082/problem/A 题目内容 一共n页书,现在位于第x位,想要看第y页,每次只能翻d页,注意总能翻到第1页和第n页. V ...

  9. NodeJs01 文件浏览器

    ES6常用新语法 前言 是时候学点新的JS了! 为了在学习NodeJs之前,能及时用上语言的新特性,我们打算从一开始先学习一下JavaScript语言的最基本最常用新语法.本课程的内容,是已经假设你有 ...

  10. google protobuf 中的proto文件编写规则

    1. 简单介绍 protobuf文件:就是定义你要的消息(类似Java中的类)和消息中的各个字段及其数据类型(类似java类中的成员变量和他的数据类型) 2. Protobuf消息定义 消息由至少一个 ...