I will try to write this article with the simplest and clearest ideas.
The so-called memory addressing is the process of translating from the address written in the instruction to the actual physical address. Because the operating system has to take care of a lot of things, it becomes complicated.
logical address → linear address → physical address
Logical address = segment + Offset
Because: the alu width in the first CPU is only 16 bits, but the address bus width is 20 bits. So set four segment registers: CS (instruction), DS (data), SS (Stack), ES (others).
16 bits per segment register, corresponding to address bus high 16 bits. The 16-bit internal address in each instruction is added to the contents of a segment register, resulting in a 20-bit actual address.
The conversion of the above 16-bit internal address to the 20-bit actual address is still the age of 8086.
In the 80386, 32-bit CPU era, many things have changed. One of the points: to implement a "protected mode". Also be compatible with past segment registers.
As a result, the previous formula was newly written as:
Logical address = segment Selector (16-bit) + offset (32-bit)
So addressing the 80386CPU is based on the previous 8086 addressing approach, as described in the Linux kernel source scenario analysis:
Can be simply recorded as: Segment Register (segment selector) → address segment description structure (segment descriptor) → address from base address → instruction + base address = Physical location
The address segment describes where the structure (segment descriptor) comes from: Add two registers to the CPU, one is the Global Segment Descriptor Table Register GDTR, and the other is the local Segment Description table register LDTR.
Segment Descriptor address = segment Selector The value in the index field x8 + GDTR/LDTR Register
This graph can show how the segment descriptor is obtained by Segment register (segment selector).
Segment selectors get the "segment" process, one is to access the Segment Description table to get the segment descriptor.
In addition, the segment descriptor can be obtained by non-programmable registers, without accessing the Segment description table.
In summary, it is the process of segment selector (segment register) → (segment descriptor descriptor →) segment descriptor → base site.
Segment Descriptor:
Continue to deduce the previous formula:
Acquisition of Segment Descriptor: Segment selector index field x8 + GDTR/LDTR value in register
Base Address = Segment Descriptor Base field
Logical address = segment Selector (16-bit) + offset (32-bit) = Segment Descriptor base field + Offset
Resources:
"Assembly language" Wang Shuang
"Linux kernel source code scenario analysis" Queen Maud
"Understanding the Linux Kernel" Daniel p. Bovet/marco Cesati
Linux Memory addressing