You are looking a different thing: boot code.
The boot code must be 16-bit, and it is special. It also requires a different assembler (16 bit, real-mode).
So, we are in 16-bit real mode, so we have segments. The .text
is for the CS segment (so offset on .text are relative to CS). .data
is expected for DS
segment, but this can be changed (and you can tell assembler, so that it will know hot to calculate the offsets).
Note: the boot code is also special because BIOS load boot code in 07C0h:0000h, and run it, but we move it, and run the second part, so the same code will have different CS segments (you may find some LONG JUMP which may seem unnecessary). Then load rest of boot code. then setup stuffs (at BIOS level and hardware level e.g. restore A20 line), then prepare the memory tables (we have still just the first MB of memory available (and some it is used by BIOS) for protected and 32-bit mode, so that we can switch, flush caches, and execute in 32-bit. And then the rest of set-up.
EDIT: add more explanation.
We are in 16 bit real mode, so the memory addresses are calculated with two components: segment and offset (both are 16-bit long, segment is shifted 4 bit). So current code is in CS:IP and usually we read data in DS segment (few exceptions, or we can explicitly give the segment).
When you assemble the code, you get different part in different segments.
.text
begtext:
The first line declare: we are now in .text
segment (text
is usually for code). Next line we declare a label: begtext
, which I assume it is for beginning of our text segment
.
You do the same for other segments (.data
and .bss
). The reason is that we want to know the initial offset, so we can move the data (we do not know if assembler or loader will put as at different offset, so it is safe to define a label at beginning, and so we can use it, if we need to move the code). You see the same at the end of the file (e.g. endtext
), to know the last point, and so the size of used segment (endtext - begtext
).
Note: we cannot move the entire segment, because segments may overlap, or CS may be DS, just with different offset, and so we risk to overwrite wrong part (in case we move code and data in a different order).
entry:
defines the entry point: you want that the loader will start at _start
. But this depends on the format of the resulting file (so assembler directives). Sometime you have org
where you explicitly tell the current position (e.g. in DOS .com
files we had org 100h
, IIRC, and that was the entry point called by DOS).
You have also the definition of some constant (07c0 is where boot sectors are loaded and executed, by BIOS on PC).
.glovl
is just to declare that values as "global", so exported and available on other modules, if you want to "link" several files.