来自: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. TouTiao开源项目 分析笔记7 加载数据的过程

    1.以新闻页中的段子数据显示为例 1.1.首先执行InitApp==>SplashActivity. 因为在AndroidManifest.xml中定义了一个<intent-filter& ...

  2. 3437: 小P的牧场

    3437: 小P的牧场 思路 斜率优化. dp[i]表示到第i个点(第i个点按控制台)的最小代价. 代码 #include<cstdio> #include<iostream> ...

  3. 剑指Offer - 九度1520 - 树的子结构

    剑指Offer - 九度1520 - 树的子结构2013-11-30 22:17 题目描述: 输入两颗二叉树A,B,判断B是不是A的子结构. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每 ...

  4. Pascal小游戏 打飞机

    一个经典的打飞机游戏(1)Pascal代码 十分经典,有一种街机的感觉 奇葩青年的又一控制台神作. uses crt; type list=record         ty,ax:integer;  ...

  5. 基于Python的selenuim自动化测试尝试

    工作这么多年了,终于狠下心好好开始学学自动化测试相关知识,揭开这层神秘的面纱. 困难重重,障碍很多,但好在每天都多少有点小收获. 很感谢一个QQ好友推荐的虫师,也非常感谢在这个契机读到了虫师编著的&l ...

  6. 孤荷凌寒自学python第十天序列之字符串的常用方法

    孤荷凌寒自学python第十天序列之字符串的常用方法 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) Python的字符串操作方法非常丰富,原生支持字符串的多种操作: 1 查找子字符串 str ...

  7. 【志银】Ubuntu Apache2配置SSL证书

    1.准备工作 证书文件:zain.crt.zain.key /etc/apache2/文件夹下新建ssl 文件夹,将证书文件放入/etc/apache2/ssl 2.配置SSL证书 打开/etc/ap ...

  8. 剑指offer-从尾到头打印链表03

    class Solution: # 返回从尾部到头部的列表值序列,例如[1,2,3] def printListFromTailToHead(self, listNode): # write code ...

  9. 1102 Invert a Binary Tree (25 分)(二叉树遍历)

    二叉树有N个结点,给出每个结点的左右孩子结点的编号,把二叉树反转(左右孩子交换  所以是后序遍历交换) 输出反转后二叉树的层序遍历和中序遍历 #include<bits/stdc++.h> ...

  10. ImportError: dynamic module does not define module export function (PyInit__caffe)

    使用python3运行caffe,报了该错误. 参考网址:https://stackoverflow.com/questions/34295136/importerror-dynamic-module ...