来自维基百科:
该段的大小由程序员在编译或组装程序之前放置在那里的值确定,并且在运行时不会改变
那么究竟是谁决定了细分市场的大小呢?操作系统?另外,什么时候计算?“在程序编译或组装之前”是否意味着它是在预处理阶段完成的?
对于传统的编译语言,答案大致是链接器。
发生的情况是每个目标文件都包含有关各个段的大小(和对齐等)的信息。当链接器将目标文件拼接在一起形成可执行文件时,它将以尊重对齐的方式聚合匹配的段。因此,部件的顺序以及最终段的潜在大小取决于链接器。
如果需要添加填充以保持对齐,则段的大小可能会发生变化。
请注意,解释或 JIT 编译的程序实际上没有段。
“编译程序之前..”部分必须指应存在哪些变量和/或常量。
数据段/段的大小由链接器计算 - 编译/组装过程的一部分,负责实际构建输出文件,包括记录此类信息的标头。
大小计算又基于参与对象模块的数据部分包含的内容。
您引用的 Wikipedia 文本是错误的或具有误导性。在汇编或编译之前不存在数据段。
数据段的构建方式如下。
在汇编中,程序员可以显式声明一个数据段并定义要放置在那里的值。当程序员使用某些功能时,一些汇编器还提供自动将数据添加到数据段的功能。例如,流水线ldr r7, =345
可能会要求汇编器将 345 放入数据段并在ldr
指令中填写其地址。
在高级语言中,编译器在处理代码时构建它需要的数据。这可以包括由程序员直接编写的常量(例如,在将高级代码转换为汇编的过程中创建的345
in或值。(例如,如果您编写了,编译器可能会将下标计算为 112 并将其存储在数据部分)。x = 345;
i = 35; y = x[i*3+7];
链接器将来自它处理的目标模块的数据段组合成一个数据段。大小只是组合数据的大小。(某些数据部分,例如 FORTRAN 公共段,可能是共享的,因此来自多个对象模块的数据是重叠的,而不是串联的。)
动态加载库时,它们的数据段不能在链接时合并,必须由加载器单独管理。所以一个正在执行的程序可能有多个数据段。