为什么进程的地址空间分为四个段(文本,数据,堆栈和堆)?

时间:2011-10-24 09:28:32

标签: memory process operating-system

为什么进程的地址空间必须分成四个段(文本,数据,堆栈和堆)?什么是advandatage?是否可能只有一个完整的大部分?

3 个答案:

答案 0 :(得分:5)

将程序拆分为内存中的部分有多种原因。

其中之一是指令和数据存储器在架构上可以是不同的和不连续的,即使用CPU内部和外部的不同指令和电路从/向其读取和写入,形成两个不同的地址空间(即从中读取代码)地址0和从地址0读取数据通常会从不同的存储器中返回两个不同的值。

另一个是可靠性/安全性。您很少希望程序的代码和常量数据发生变化。大多数情况下,当发生这种情况时,它会发生错误(无论是在程序本身还是在输入中,可能是恶意构造的)。你想防止这种情况发生,并知道是否有任何尝试。同样,您不希望可以更改的数据区域可执行。如果它们存在并且程序中存在安全漏洞,当恶意代码将其作为数据进入程序数据区并触发那些安全漏洞(例如缓冲区溢出)时,程序很容易被迫做一些有害的事情。

另一个是存储......在许多程序中,许多数据区域根本没有初始化或被初始化为一个公共预定义值(通常为0)。当程序加载并即将启动时,必须为这些数据区保留内存,但这些区域不需要存储在磁盘上,因为那里没有有意义的数据。

在某些系统上,您可以将所有内容放在一个位置(部分/段/等)。这里有一个值得注意的例子是MSDOS,其中.COM风格的程序没有结构,只有它们的大小必须小于64KB,第一个可执行指令必须出现在文件的最开头,并假设它的位置对应于IP = 0x100(其中IP是指令指针寄存器)。如何在.COM程序中放置和交错代码和数据并不重要,直到程序员。

还有其他架构工件,例如x86段。同样,MSDOS是处理它们的操作系统的一个很好的例子。其中的.EXE风格的程序可能有多个直接对应于x86 CPU段的段到实模式寻址方案,其中通过称为段的64KB长“窗口”查看内存。这些窗口/段的位置相对于CPU的段寄存器的值。通过更改段寄存器值,您可以移动“窗口”。为了访问超过64KB,需要使用不同的段寄存器值,这通常意味着在.EXE中有多个段(不仅可以是一个段用于代码,一个用于数据,还可以用于其中任何一个段)。

答案 1 :(得分:3)

至少文本和数据段是分开的,以防止存储在变量中的恶意代码被运行。

指令(已编译的代码)存储在文本段中,而变量的内容存储在数据段中,后者永远不会被执行,只能读取和写入。

多一点信息here

答案 2 :(得分:0)

这种区别对于将安全性修补到von-Neumann体系结构(数据和指令共享相同内存)是不是一个大的,愚蠢的解决方法?