清華OS前置知識:80386處理器

保護模式在實模式下初始化控制寄存器,如(GDTR,LDTR等)以及頁表,然後通過設置CR0寄存器使其中的保護模式使能位置位,進入保護模式,該模式下80386支持優先級機制,不同的程序運行在不同的特權級上,共0~3四個級別,操作系統在最高的特權級0上

不同模式下尋址方式:

物理地址:內存中的真實地址

實模式下

邏輯地址:段地址和偏移地址

邏輯地址=物理地址,因爲此時沒有分段或分頁機制(所謂的段地址是人爲看作一個段的首地址,而不是系統的機制)

實模式下每一個指針都指向實際的物理地址,可以輕易修改其中的內容,不安全

保護模式下

線性地址:線性地址空間中的一個地址

線性地址空間是80386處理器通過段機制控制下形成的地址空間,在操作系統的管理下,每個運行的用程序有相對獨立的一個或多個內存空間段,每個段有各自的起始地址和長度屬性,這樣使應用程序之間相互隔離,實現對地址空間的保護

邏輯地址(也稱虛擬地址):16位段選擇子 + 32位段內偏移

int boo = 1;
int *foo = &boo;

boo是一個整型變量,foo變量是一個指向boo地址的整型指針變量,foo中存儲的內容就是boo的邏輯地址

系統採用段式管理機制來實現邏輯地址到線性地址的轉換

未啓動啓頁機制時,邏輯地址(通過段基址處理)生成線性地址=物理地址

在頁機制開啓後,邏輯地址(通過段機制處理)生成線性地址,隨後生(通過頁機制處理)成物理地址。

關於實模式和保護模式下的尋址:

因爲8086CPU地址總線爲20位而寄存器、數據總線只有16位,無法存儲和傳送20位的數據,纔不得不採取段地址左移4位的方式。

32位機的數據總線、寄存器、地址總線都是32位,可直接給出一個32位數就能找到對應的地址,因此不再需要段地址左移的用法,但是爲了向下兼容,保留了16位尋址模式,即實模式

保護模式下的尋址可以採取基址+偏移的方式,但不同的是,這裏的基址無需進行左移處理,所有的32位的通用寄存器都可以作爲基址寄存器(存儲basepointer),除ESP之外的通用寄存器都可以作爲變址寄存器(存儲indexpointer),變址寄存器允許乘以1/2/4/8作爲比例因子(indexscale),最後還允許加上一共8/32位的偏移量(immed32)

AT&T:immed32(basepointer, indexpointer, indexscale)	
	  =imm32 + basepointer + indexpointer x indexscale
Intel:	[basepointer + indexpointer x indexscale + imm32]

要注意,儘管通用寄存器、標誌寄存器都已經擴展到32位,但段寄存器依舊是16位的,可以理解爲爲了兼容8086PC機的段地址:偏移地址的尋址方式

在保護模式下使用段地址:偏移地址的尋址模式時(即使用分段機制),段寄存器中存放的不再是段基址了,而是存放了一個段選擇子,又稱段選擇符,一個選擇子對應一個長64-bit的描述符,其中有32bit是段基址,另32位存儲着段的長度、屬性等內容,由於內存中不止一個段,因此也需要多個段描述符,所以把段描述符集中存儲在一塊連續的存儲空間裏,排上序號,這就有了描述符表GDT,因此我們需要先找到描述符表的基地址,在32位CPU中,有一個48位的專用寄存器GDTR存儲着全局描述符表的基地址等信息,而段寄存器中選擇子的高13位存儲着相應描述符的序號,段寄存器的功能就是選擇描述符,所以也把段寄存器叫做段選擇器,在得到了段的基地址,加上了偏移地址以後(段地址無需左移),我們便得到了“中間地址”–線性地址,接着通過頁機制最終得到物理地址,當然,如果沒有頁機制,則線性地址就是物理地址了

32

9

參考博客:計算機地址與8086尋址方式以及32位處理器的尋址方式

32位cpu尋址小結

32位保護模式內存尋址原理

80386CPU加電後的第一條指令問題

80386CPU將BIOS ROM編址在32位內存地址空間的最高端,即4GB地址的最後一個64KB內

解釋:如果和8086一樣,把BIOS編址在1MB內存地址空間的最高64KB中,因爲BIOS是隻讀的,則內存(這裏指RAM)就會被一塊ROM分隔成不連續的兩端,很不協調

加電之後,CPU進入實模式,將CS的值設置爲0xF000,CS的shadow register的Base值初始化爲0xFFFF0000,EIP寄存器初始化爲0x0000FFF0,所以第一條指令的物理地址爲0xFFFFFFF0

解釋:雖然說實模式下計算地址需要CS中的地址進行移位,但是Intel規定這種計算方式是在CS中的初始值被改變以後才使用,所以未改變之前是用Base+EIP的計算方式

解釋上面的解釋:上面提到的Base,是一個寄存器,而不是GDT中的base(這時候還沒有GDT),現代的CPU爲每個段寄存器增加了兩個寄存器:Base和Limit,它們的值不能通過指令讀寫,而是由CPU自動設置的

補充:在實模式下,Base寄存器的值等於CS的值左移4位,在保護模式下,根據段選擇子在GDT中找到對應段描述符,其中base部分的值會更新到對應段寄存器的Base寄存器中,然後進行基址+偏移地址的計算

總結:歸根結底,80386地址的計算方式都是Base+IP/EIP,只不過Base寄存器中的值在不同情況下來源不同,可以是初始狀態下的值,可以來自對CS值的移位,也可以來自GDT表

該地址上有一條長跳轉指令,該長跳轉指令會更新CS寄存器和它的shadow register,執行完後,表面CS沒有變化,但其shadow register已經被更新,其Base值爲0x000F0000,此時的物理地址爲0x000FE05B。此時的地址在1M以內了,且位於RAM 中,Intel設計了一種映射機制,將高地址的BIOS ROM映射到1MB以內的RAM空間,使其具有隻讀屬性,即1M空間裏最高的64KB的內容和4GB裏最高的64KB的內容相同

Intel 80386寄存器

通用寄存器:EAX/EBX/ECX/EDX/ESI/EDI/ESP/EBP,低16位就是8086的AX/BX/CX/DX/SI/DI/SP/BP

寄存器 含義
EAX 累加器
EBX 基址寄存器
ECX 計數器
EDX 數據寄存器
ESI 源地址指針寄存器
EDI 目的地址指針寄存器
EBP 基址指針寄存器
ESP 堆棧指針寄存器

段寄存器:除了8086的CS/DS/ES/SS,增加了FS/GS,都是16位的,用於不同屬性內存段的尋址

注:CS在實模式和保護模式下有着不同的含義

寄存器 含義
CS 代碼段(Code Segment)
DS 數據段(Data Segment)
ES 附加數據段(Extra Segment)
SS 堆棧段(Stack Segment)
FS 附加段
GS 附加段

指令指針寄存器:EIP的低16位就是8086的IP,存儲下一條要執行指令的內存地址,在分段地址轉換中,表示指令的段內偏移地址

標誌寄存器:EFALGS,比8086的16位標誌寄存器增加了4個控制位,共20個控制位

CF(Crray Flag):進位標誌位
PF(Parity Flag):奇偶標誌位
AF(Assistant Flag):輔助進位標誌位
ZF(Zero Flag):零標誌位
SF(Signal Flag):符號標誌位
IF(Interrupt Flag):中斷允許標誌位,由CLI,STI控制
DF(Direction):向量標誌位,由CLD,STD控制
OF(Overfolw Flag):溢出標誌位
IOP(I/0 Privilege Level):I/O特權級字段,寬度2位,指定了I/O指令的特權級,如果當前特權級別在數值上小於或等於IOPL,則可執行,否則發生一個保護性故障中斷
NT(Nested Task):控制中斷返回指令IRET,寬度爲1,若NT=0,則用堆棧中保存的值恢復EFALGS,CS,EIP。從而實現中斷返回,若NT=1,則通過任務切換實現中斷返回,在ucore中,設置NT爲0

還有一些應用程序無法訪問的控制寄存器,如CR0,CR2,CR3……

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