邏輯地址(Logical Address)
包含在機器語言指令中用來指定一個操作數或一條指令的地址。每一個邏輯地址都由一個段和一個偏移量組成,偏移量指明瞭從段的開始到實際地址之間的距離。
線性地址(Linear Address)
是一個32位無符號整數,可以用來表示高達4GB的地址。
物理地址(Physical Address)
用於存儲器芯片級存儲器單元尋址。物理地址由32位無符號整數表示。
CPU控制單元通過一種稱爲分段單元(segmentation unit)的硬件電路把一個邏輯地址轉換成線性地址;接着,第二個稱爲分頁單元(paging unit)的硬件電路把一個線性地址轉換成物理地址。
硬件中的分段
從80386模型開始,Intel微處理器以兩種不同的方式執行地址轉換,這兩種方式分別稱爲實模式和保護模式。
段寄存器
一個邏輯地址由兩部分組成:一個段標識符和一個指令段內相對地址的偏移量。段標識符是一個16位長的字段,稱爲段選擇符(Segment Selector),而偏移量是一個32位長的字段。CPU提供了6個段寄存器cs、ss、ds、es、fs和gs來存放段選擇符,以快速方便地找到段選擇符。其中3個段寄存器有專門的用途:cs爲代碼段寄存器,指向包含程序指令的段;ss爲棧段寄存器,指向包含當前程序棧的段;ds爲數據段寄存器,指向包含靜態數據或者外部數據的段,而剩下的es、fs和gs都只能用作數據段寄存器。也就是說,在某個時刻,對程序員來說,存儲器最多由6個段組成,1個代碼段,1個棧段和最多4個數據段。
段描述符
每個段由一個8字節的段描述符(Segment Descriptor)表示,它描述了段的特徵。段描述符放在全局描述符表(Global Descriptor Table, GDT)或局部描述符表(Local Descriptor Table, LDT)中。通常只定義一個GDT,而每個進程除了存放在GDT中的段之外,如果還需要創建附加的段,就可以有自己的LDT。GDT在主存中的地址存放在gdtr寄存器中,當前正被使用的LDT的地址存放在ldtr寄存器中。段寄存器中僅僅存放段選擇符,每個段選擇符包含一下字段:13位的索引,用於選擇8192(213)個全局描述符或局部描述符中的一個;TI標誌指明段描述符是在GDT中(TI = 0)或在LDT中(TI = 1);2位RPL字段,用於表示請求者的特權級。
參考文獻:
1. 深入理解Linux內核 第二版
2. Linux內核完全註釋
3. Intel 80386 Programmer's Reference Manual 1986