從8086的實模式到80386的保護模式的地址映射發展

一、x86體系結構的發展歷史:

1.常見處理器:

  • inter:pc主流的處理器;
  • AMD:部分pc電腦;
  • arm:主要用於手機和平板等;
  • ppc,mips:主要用於一些智能眼鏡、只能手錶等智能可穿戴設備。

2.CPU位數含義:

CPU的位數代表着CPU的計算能力,即就是ALU的計算能力,即ALU一次能夠計算的最大寬度,最長的字節長度,也就是做加法。
CPU位數 == ALU的寬度,ALU需要從寄存器取數據,寄存器數據來自數據總線,也就是:
CPU位數 == ALU的寬度 == 數據總線的條數。

地址總線的條數代表:可以訪問的地址範圍,假設地址總線16條,可以訪問的最大地址爲2^16

3.x86體系開創過程:

  • x86體系始於8086,實際上真正意義上的32位的x86體系從80386開始的,80186、80286都是過渡階段;

二、8086地址映射簡介:實模式

1.訪問過程:

  • 地址總線:20條(可訪問最大地址爲2^20,即1M)
  • 數據總線:16條(總線上數據最大能傳遞2字節寬度的數據)

我們發現,數據總線中無法存放20位的地址,因爲數據總線最大寬度爲16位,此時引入4個16位的寄存器:IP寄存器存放地址的偏移量

  • CS:code section 指令寄存器
  • DS:data section 數據寄存器
  • SS:stack section 堆棧寄存器
  • ES:expand section 擴展寄存器

8086將物理內存劃分爲不同的段,正如寄存器名一樣,指令段、數據段、堆棧段、擴展段等。
此時,規定每個內存段的起始地址爲16的倍數,[16,2^16],然後將每個段的起始地址保存在對應的寄存器中,但是由於寄存器是16位的,地址都是20位的。

num % 16 == 0
一個數字可以被16整除,二進制的低四位全部爲0,只需要將內存段的地址的高16位保存在寄存器中
即DS>>4,去掉低4位

所以,最終寄存器中保存的都是不是真正的段起始地址,而是段起始地址的高16位。

假設訪問數據段的一個變量,過程如下

  1. 訪問DS寄存器,獲得數據段的起始地址;
  2. 將寄存器中獲得值左移4位,DS<<4,恢復成20位的地址;
  3. 最後,加上該數據在內存段上的偏移量IP
數據的最終地址: DS<<4 + IP
其中,IP又被稱爲偏移量、偏移地址、邏輯地址

這裏的分段是指對物理內存的分割,與段頁式管理沒聯繫,段頁式管理式在有操作系統的情況下,而這裏並沒有操作系統。

2.8086存在的缺點:

  1. 沒有操作系統的存在,直接訪問的是物理內存;
  2. 對內存沒有進行權限控制,可以任意的對某一塊內存進行修改;
  3. 沒有對ip進行安全檢查,如果ip特別大,產生越界訪問等不好的後果。

直接對物理內存進行操作,沒有操作系統保護,此狀態被叫做實模式,也叫實地址模式。

3.linux內核image加載:

  • CPU剛通電,操作系統還沒有運行起來,CPU強制進入實模式,也就是8086運行的模式,也就是此時的CPU最多可以訪問1M的內存;
  • 這也就是說爲什麼內核從1M以後開始加載,0x100000,1M內存放的式bois的緩存,顯卡的緩存,驅動代碼等內容。因爲1M前放的內容式必須要先訪問或者執行的。

三、80386的地址映射:保護模式

1.80386的新突破:

從8086得出一些經驗,8086是極其不安全不可靠的,原因如下:

  • 沒有內存段的大小說明;
  • 沒有內存訪問權限的控制;
  • 內存的起始地址也可能被修改。

所以,後來,80386改善和解決8086存在的弊端,新增兩個32位寄存器:

  1. GDTR:全局段描述符表,保存全局段描述符表GDT的地址,常駐內存,進程共享
  2. LDTR:局部段描述符表,進程獨享,新版本中淘汰

GDT中的內容:GDT就是一個數組,保存內存段的信息
在這裏插入圖片描述
GDT數組的索引存放在哪裏:

從80386開始,CS DS SS ES用來存放段描述表的索引

此時這四個段寄存器的16位的含義不再是保存段起始地址,而是用來描述GDT數組的信息,如下
在這裏插入圖片描述

  • 權限:00代表最高權限,也就是內核態,11代表最低權限,也就是用戶態;
  • 8192:2^13 = 8k;也就是有這麼多的索引,即GDT[2^32-1],實際上,linux內核也會佔用一部分,大概是12個左右被內核保留使用,實際上用戶可以使用的是8180個。

GDT數組的某一項的含義: GDT[n],每一項元素大小爲8字節,64位

在這裏插入圖片描述

  • B:base addr 起始地址,總共32位
  • L:length 段內存長度,總共16位,2^16 = 1M,單位G表示
  • G:表示段內存長度的單位:0表示以字節位單位,1表示段內存長度單位是頁面
  • D、A、P、DPL、S:權限控制

2.保護模式下內存分段的地址映射:
在這裏插入圖片描述

GDT[DS>>3].baseaddr + IP(邏輯地址,需要和length比較一下,防止越界) = 線性地址
當基地址GDT[DS>>3].baseaddr ==0時,IP == 邏輯地址 == 線性地址

DS>>3:獲取高13位,也就是GDT數組的索引
GDT[DS>>3]:GDT數組的某一項
  • 獲取到線性地址以後,檢查是否開啓分頁機制,如果沒有開啓,即線性地址 == 物理地址;
  • 開啓了分頁機制,此時線性地址 == 虛擬地址,要進行分頁地址映射,才能得到物理地址。

3.補充提升:

  • CR0:最高位,即PG位,0代表未開啓內存分頁,1代表開啓內存分頁
  • CR2:發生缺頁異常的虛擬地址
  • CR3:頁目錄的起始地址
  • CR4:PAE位,物理地址擴展,0表示位開啓,1表示開啓

總線有外總線和內總線之分,我們程序中打印的地址是內總線發出的地址,也就是虛擬地址,即沒有經過頁表映射,沒有經過轉換的地址;
只有當虛擬地址經過了頁表映射等過程,纔會被放到外總線上,而外總線是直接連接內存的總線。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章