Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C编译程序使用什么段?_C_Windows_Memory Segmentation - Fatal编程技术网

C编译程序使用什么段?

C编译程序使用什么段?,c,windows,memory-segmentation,C,Windows,Memory Segmentation,我在OSDev wiki上读到,x86体系结构的受保护模式允许您为代码和数据创建单独的段,而不能写入代码段。Windows(是的,这就是平台)将新代码加载到代码段中,并在数据段上创建数据。但是,如果是这种情况,程序如何知道它必须将段切换到数据段?因为如果我理解正确,所有adress指令都指向运行代码的段,除非切换描述符。但我也读到,这样收集的平面内存模型允许您在一个段内运行代码和数据。但我读这篇文章只是为了和汇编程序有关。那么,请问,Windows上的C编译代码是什么情况?谢谢。解释中的段有两种

我在OSDev wiki上读到,x86体系结构的受保护模式允许您为代码和数据创建单独的段,而不能写入代码段。Windows(是的,这就是平台)将新代码加载到代码段中,并在数据段上创建数据。但是,如果是这种情况,程序如何知道它必须将段切换到数据段?因为如果我理解正确,所有adress指令都指向运行代码的段,除非切换描述符。但我也读到,这样收集的平面内存模型允许您在一个段内运行代码和数据。但我读这篇文章只是为了和汇编程序有关。那么,请问,Windows上的C编译代码是什么情况?谢谢。

解释中的段有两种含义:

  • 8086存储器地址段
  • 对象模块程序段
第一个与加载到80386+段寄存器中的内容有关;它包含一个物理内存开始地址、内存分配长度、允许的读/写/执行访问,以及它是从低增长到高,还是从高增长到低(加上一些更模糊的标志,如“引用时复制”)

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

就x86执行指令而言,每个操作数都有一个相关的段寄存器。有时是明确的,有时是含蓄的。代码通过CS进行隐式访问,通过SS进行堆栈,这在涉及ESPEBP寄存器时是隐含的,而对于大多数其他操作数则是隐含的DS<代码>ES、
FS
GS
在所有其他情况下都必须指定为覆盖,但一些字符串指令除外,如
MOV
cmps
。在平面模型中,所有段寄存器映射到相同的地址空间,尽管CS不允许写入


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

您读取的信息已过时。自1993年以来的Windows版本使用平坦的32位虚拟内存空间。CS和DS段寄存器的值不再重要,无法更改。代码与数据的概念仍然存在,现在由内存页属性实现。检查在的flNewProtect参数中传递的允许值


您自己很少使用此API,属性由可执行图像加载程序和堆管理器设置。

CS和DS的值仍然很重要-它们必须引用GDT或LDT中的有效描述符。此外,
DS
可以在用户模式下更改(但大多数程序不这样做,因为它很少有用)。谢谢,但我认为在保护模式下,您仍然有分段,现在使用描述符表而不是分段寄存器。但在每个描述符表中,无论是其代码还是数据,都有一个放置概念的位置。但是平面模式表示代码和数据在同一段中,我所说的段是指一个描述符表条目。