https://sourceware.org/binutils/docs-2.28/as/Sections.html
粗略的讲,一个section是一个地址范围,没有间隙。该地址范围内的所有数据都有相同的目的,例如,可以有一个只读section。
链接器ld从多个目标文件(partial programs)读取内容,结合成一个可执行程序。当as生成一个目标文件时,这个partial program假定地址从0开始。ld为partial program分配最终的地址,保证不同的partial program地址不重叠。这过度简化了,但是足够解释as怎么使用sections。
ld将你的程序的地址块移动到它们的运行地址,这些块以一个整体滑向它们的运行地址。即它们的长度不变、内部的字节顺序也不变。这一个整体叫做section。将运行地址赋给sections叫做relocation。
as生成的目标文件至少有3个sections,它们中的任何一个可以为空。这3个sections为text, data和bss section。
生成COFF或ELF格式的输出时,as也能产生任何你通过.section指令指定的其它名字的section。如果你未使用任何指令将输出放到.text或.data sections,这些sections仍将存在,但是为空。
在目标文件内部,text section的地址从0开始,data section和bss section依次跟在后面。
为了让ld知道重定向时,哪些数据需要改变,以及如何改变。as也将重定向信息写入目标文件。为了执行重定向,ld必须知道地址的每一次引用:
在哪个地方引用该地址。
引用的字节长度是多少。
地址指向哪个section。
地址在section的偏移是多少。
引用地址是否为Program-Counter relative。
事实上,as使用的每一个地址,可以表示为:
(section) + (offset into section)
进一步说,as计算的大多数表达式有这个section-relative特性。
在本手册中,我们使用{secname N}约定,表示相对于secname偏移N字节。
除了text,data和bass sections,你需要知道absolute section. 当ld混合partial programs时,absolute section的地址保持不变。链接时,两个partial grogram的data section绝不会重叠,但是absolute sections必须重叠(可认为从0开始的整体上的重叠)。
section的想法可以扩展到undefined sections. 汇编阶段,任何section未知的地址,定义上表达为{undefined U},产生未定义地址的唯一方式是引用一个未定义符号。
ld处理4种不同特性的sections。
named sections / text section / data section
bss section
absolute section
undefined section
这些sections仅供as内部使用,它们在运行时没有意义,大多数情况下,你实际上不需要知道这些sections。但是它们可能出现在as警告消息中。所以了解他们还是有帮助的。这些sections用来允许汇编语言中的表达式的值成为section-relative地址。
expr section
汇编器内部将复杂的表达式存储为符号的结合,当需要将表达式表达为一个符号时,将它放入expr section。
照惯例,汇编出的字节存储到两个sections:text和data。有一种应用场景,你可能在section中有多组独立的数据,要求在目标文件中,同组数据互相靠近,尽管他们在汇编源代码中不连续。as使用subsections实现这种目的。每个section允许0到8192编号的子section。
例如,你想把常量存储到text section,但是不想它们和代码混合在一起,这种情况下,可以将代码放入'.text 0',把常量放入`.text 1'。
subsections是可选的,如果没有使用,所有的东西可认为编号为0。
每个子sections填充0,以对齐到4字节。
子sections在目标文件中按数学顺序出现,最低的编号优先级最高。目标文件不包含子section的信息。
为了指定哪个子section可以使用`.text expression'或者`.data expression'。
使用.lcomm定义一个bss section的符号。
.comm是另一种形式的未定义符号。
对于ELF格式,也可以使用.bss切换到bss section。