我在Osdev Wiki上阅读了X86体系结构的保护模式,使您可以为代码和数据创建单独的段,而您无法写入代码部分。该Windows(是的,这是平台)将新代码加载到代码段中,并且在数据段上创建了数据。但是,如果是这种情况,那么程序如何知道它必须将段转换为数据段?因为如果我理解正确,则所有adress指令都指向您从代码运行的段,除非您切换描述符。但是我还读到,因此综合的平面内存模型允许您在一个段内运行代码和数据。但是我仅与汇编程序有关。那么,请在Windows上使用C编译代码的情况是什么?谢谢。

有帮助吗?

解决方案

有两个含义 分割 在解释中:

  • 8086内存地址段
  • 对象模块程序部分段

第一个与加载到80386+段寄存器中有关的内容;它包含一个物理内存开始地址,内存分配长度,允许的读/写入/执行访问,以及它是否从低到高或反之亦然(加上一些更晦涩的标志,例如“参考复制”)。

第二个含义是对象模块语言的一部分。基本上,有一个命名 code, ,名为 data (其中包含初始化数据),并进行非直接数据的细分 bss (以1960年代召集人的伪指示命名 从符号开始的块)。当链接器将对象模块组合在一起时,它将所有代码段,所有数据段共同将所有代码段组合在一起,将BSS和BSS组合在一起。当加载程序映射内存地址时,它将查看总代码空间并分配至少该大小的CPU内存分配,并将段映射到代码(在虚拟内存情况下)或将代码读取为分配的内存 - 它必须暂时将内存设置为数据可写。写保护是通过CPU的分页机制以及细分寄存器完成的。这是为了保护代码写作尝试,例如错误的数据地址。加载程序还为两个数据段组进行类似的设置。 (除此之外,还设置了一个堆栈段并分配它,并映射共享图像。)

至于X86执行指令,每个操作数具有关联的段寄存器。有时这些是明确的,有时它们是隐式的。代码是隐式访问的 CS, ,堆叠 SS 每当 ESP 或者 EBP 注册涉及,以及 DS 对于大多数其他操作数暗示。 ES, FS, , 和 GS 在所有其他情况下,必须将其指定为覆盖,除了某些字符串指令 movscmps. 。在平面模型中,所有细分寄存器映射到相同的地址空间,尽管CS不允许写作。

因此,为了回答您的最后一个问题,CPU立即设置了四个(或更多)段寄存器,以访问该过程的平坦虚拟内存空间。检查每个操作数访问是否适合指令(例如不增加 CS 地址),并由分页保护单元检查是否允许。

其他提示

您阅读的信息已过时。自1993年以来,Windows版本使用平坦的32位虚拟内存空间。 CS和DS段寄存器的值不再重要,不能更改。仍然有一个代码与数据的概念,现在由内存页面属性实现。查看在flnewProtect参数中通过的允许值 VirtualProtectex()API函数.

您很少自己使用此API,属性由可执行的Image Loader和Heap Manager设置。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top