Roughly, a section is a range of addresses, with no gaps; all data between those addresses is treated the same for some particular purpose. For example, there may be a read only section.
The linker reads many object files (partial programs) and combines their contents to form a runnable program. When the assembler emits an object file, the partial program is assumed to start at address 0x00000000. The linker assigns the final addresses for the partial program, so that different partial programs do not overlap. This is actually an oversimplification, but it suffices to explain how the assembler uses sections.
The linker moves blocks of bytes of your program to their run-time addresses. These blocks slide to their run-time addresses as rigid units; their length does not change and neither does the order of bytes within them. Such a rigid unit is called a section. Assigning run-time addresses to sections is called relocation. It includes the task of adjusting mentions of object-file addresses so they refer to the proper run-time addresses.
An object file written by the assembler has at least three sections, any of which may be empty. These are named text, data and bss sections.
When it generates COFF output, the assembler can also generate whatever other named sections you specify using the ".section" directive (see .section). If you do not use any directives that place output in the ".text" or ".data" sections, these sections still exist, but are empty.
Within the object file, the text section starts at address 0x00000000, the data section follows, and the bss section follows the data section.
To let the linker know which data changes when the sections are relocated, and how to change that data, the assembler also writes to the object file details of the relocation needed. To perform relocation the linker must know, each time an address in the object file is mentioned:
Where in the object file is the beginning of this reference to an address?
How long (in bytes) is this reference?
Which section does the address refer to? What is the numeric value of
Is the reference to an address "Program-Counter relative"?
In fact, every address the assembler ever uses is expressed as
Further, most expressions the assembler computes have this section-relative nature.
In this manual we use the notation {secname N} to mean "offset N into section secname."
Apart from text, data and bss sections you need to know about the absolute section. When the linker mixes partial programs, addresses in the absolute section remain unchanged. For example, address {absolute 0} is relocated to run-time address 0 by the linker. Although the linker never arranges two partial programs' data sections with overlapping addresses after linking, by definition their absolute sections must overlap. Address {absolute 239} in one part of a program is always the same address when the program is running as address {absolute 239} in any other part of the program.
The idea of sections is extended to the undefined section. Any address whose section is unknown at assembly time is by definition rendered {undefined U}—where U is filled in later. Since numbers are always defined, the only way to generate an undefined address is to mention an undefined symbol. A reference to a named common block would be such a symbol: its value is unknown at assembly time so it has section undefined.
By analogy, the word section is used to describe groups of sections in the linked program. The linker puts all partial programs' text sections in contiguous addresses in the linked program. It is customary to refer to the text section of a program, meaning all the addresses of all partial programs' text sections. Likewise for data and bss sections.
Some sections are manipulated by the linker; others are invented for use of the assembler and have no meaning except during assembly.