免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3950 | 回复: 5
打印 上一主题 下一主题

怎样理解操作系统中“栈”的概念? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-05-24 17:30 |只看该作者 |倒序浏览
请教:
操作系统中的“栈”是和“堆”是什么意思?
操作系统中的“栈”和数据结构中“栈”的意思是不是一样啊?
多谢了~

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2004-05-24 17:35 |只看该作者

怎样理解操作系统中“栈”的概念?

》》操作系统中的“栈”和数据结构中“栈”的意思是不是一样啊?
是的。
》》堆
你用malloc时,申请的空间就是从堆里分来的。
它就是一个内存池,你可以申请所需空间,
用完后再放回去。

BTW,既然你问操作系统中的这些概念,
难道书上没有讲吗????????

论坛徽章:
0
3 [报告]
发表于 2004-05-27 08:51 |只看该作者

怎样理解操作系统中“栈”的概念?

忘记了-_-b

俺原来的意思是说,在c的函数中,函数的变量的内存都在栈上对把(除了用new 和malloc申请的外),当这个函数的调用结束的时候,这些变量就会销毁对把,
那为什么这些变量的内存是在栈中分配的而不是在堆中分配的呢?
还有,这个栈也符合后进先出的原则吗?我定义变量 char a,b;
那么,在程序运行时,如果想取得a的值是不是先要把b取出来?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
4 [报告]
发表于 2004-05-27 15:38 |只看该作者

怎样理解操作系统中“栈”的概念?

为什么要在堆中分配?

这个栈是系统自动分配的,你一般是不能访问的。

忘了,那就找书再来看看。

论坛徽章:
0
5 [报告]
发表于 2004-05-27 16:05 |只看该作者

怎样理解操作系统中“栈”的概念?

从CPU角度来说的栈指的是CPU有个积存器SS,这个寄存器的低16 bit连同ESP一同指向下一次堆栈操作(push和pop)所要使用的堆栈地址。这个寄存器也可以被装入任意数值,你可以通过入栈和出栈操作来给他赋值,不过由于堆栈对于很多操作有很重要的意义,因此,不正确的修改有可能造成对堆栈的破坏。

/////////////////////////////////////////////////////////////////
从内存来说:(如下图)

操作系统代码   
                 
系统DLL
内存映射文件

用户DLL

内存分配堆
进程堆栈

全局数据区
进程代码

DOS/win16
兼容区域

空指针区域

(说明):
从内存管理角度看,堆栈是就是一块连续的内存空间,对它的操作采用先入后出的规则,他的生长方向与内存的生长方向正好相反,也就是说它是从高地址向低地址生长.从Win32程序内部的角度看,每一个线程有自己的堆栈,它主要用来给线程提供一个暂时存放数据的区域,程序使用POP/PUSH指令来对堆栈进行操作.
堆栈里面都放什么东西:
堆栈中存放的信息包括:当前正在执行的函数的局部变量,函数返回地址,该函数的上层函数传给该函数的参数,EBP的值,一些通用寄存器(EDI,ESI…)的值,注意这里提到的正在执行的函数,比如有下面的一段C代码:
   void B()
   {printf(“B\n”);}
   void A()
   { B();}
   那么当程序执行到B函数的printf函数的时候我们说正在执行的函数包括A和B而不仅仅是B函数,这一点需要注意.
堆栈是什么时候建立起来的,大小是多少?
   堆栈是在我们的main主函数被系统调用之前被建立起来的,对于非主线程它是在线程被建立之前创建的,它的默认大小是1M,如果需要修改堆栈的大小的话可以在VC6++中通过使用/STACK编译项实现:
#pragma comment(linker,"/STACK:2048,1024"  // 预约(Reserve)2M,提交(Commit)1M
关于预约(Reserve)和提交(Commit)的概念请参看”Programming Applications for Microsoft Windows“( Jeffrey Richter,Chapter 15 Using Virtual Memory in Your Own Applications)
堆栈默认为1M,当我门的程序超过了1M怎么办?
系统通过使用异常捕获(Exception Handling)机制来捕获应用程序企图去访问超过该程序提交(Commit)的堆栈范围这种异常,假如你程序预约了2M并且提交了1M大小的堆栈,那么当你的程序企图访问超过1M的范围的时候会产生一个异常并且被系统捕获,系统会帮你继续从另外1M预约的内存中提交内存来满足你的需求,如果你要求提交的大小甚至超过了2M(你一开始预约的大小)在 NT系统下(98除外)系统也会尝试去分配(allocate)内存来满足你,但是系统并不保证分配会成功
什么叫stack frame?
Stack Frame这个词你可以在各种各样的汇编书籍中看到,到底它表示什么意思呢?也许你看完文章的后半部分就会明白,在此我们先给它一个定义,你看完我下面的例子就会知道它的确切含义了,Stack Frame是堆栈中的一块区域,它保存着一个函数的返回地址,和该函数内部使用的局部数据(Local Data),它是由函数入口处的SUB ESP,48h之类的语句来建立的.
在一次函数调用过程中,堆栈是如何操作的????
假设我们的主角叫A函数…
  a.首先上级函数传给A函数的参数被压入堆栈中(至于是谁来做这个压栈操作取决于A函数的调用方式:是__stdcall, __cdecl还是其他);
  b.然后是返回地址(A函数执行完后接下来程序继续执行的地址)入栈;
  c.接下来是当前的EBP;
  d.如果A函数有局部变量,就在堆栈中开辟相应的空间以构造那些变量变量(A函数执行结束,这些局部变量的内容将被忽略/遗弃,但是不被清除,比如A函数中有一个变量int m存在于地址0x0012FFCC处,函数结束时9依然存在于0x0012FFCC处没有被清除,但是此时它已经没有任何意义了,  
  e.在函数返回的时候,弹出EBP,恢复堆栈到函数调用前的地址,弹出返回地址到EIP以继续执行程序。
调用约定
在Win32中,有关函数的调用主要有两种约定。
1._stdcall
        以__stdcall方式调用的函数有以下特征:
    •  参数由右至左压栈
    • 调用返回时,堆栈由被调函数调整
2.__cdecl
__cdecl约定是C/C++函数的默认调用约定。它有以下特征:
    • 参数由右至左压栈
    • 调用返回时,堆栈由调用者调整
/////////////////////////////////////////////////////////

从数据结构角度来说,栈只是一种算法,先进后出。

以上说法都是针对WIN平台。

论坛徽章:
0
6 [报告]
发表于 2004-05-28 13:14 |只看该作者

怎样理解操作系统中“栈”的概念?

万分感谢xhl ~~您的详细的解释让我明白了
这个问题的起因是别人问我数据结构中的栈,我回答他了。他又问:那操作系统中的堆栈也是这个样子的吗?我就晕了~

现在俺明白了,数据结构中的栈就是一种后进先出的算法。
而操作系统(咱们常见的x86上win系统)上的栈应该是内存管理的区域吧
为什么要有他的存在呢,为了在函数调用的时候传递参数,在调用一个函数的时候,先把参数以及环境压栈,然后进行函数调用。
被调用的函数在堆栈中就可以得到传递的参数了,
当这个函数执行完毕后,把上面的数据(参数等等)弹出栈,最下面的就是函数返回的地址娄~
这里有一个问题,就是这个函数自己的变量和函数的返回值都是方在一起的,也就是说,在函数里,如果你“无意?”的更改了函数临时变量
比如char s[2],你用strcpy(s,"ddddd";,就是负给s一个大的字符串。就可以把函数自己返回的地址更改吧,哪个“ddddd”应当比s 的空间大,而且要把堆栈中的函数返回地址覆盖为我们想要的地址,  然后函数结束的时候就可以跳转到我们设定的任意地址了~
这个就是缓冲区溢出攻击的原理吧~~~
不知道俺这样想对不对,大家一起讨论啊

再次感谢xhl兄,现在象你这样水平高又耐心帮助初学者的人不多了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP