X86 CPU 工作模式

1.概述

1.實模式

實模式又稱實地址模式,實,即真實,這個真實分為兩個方面,一個方面是運行真實的指令,對指令的動作不作區分,直接執行指令的真實功能,另一方面是發往內存的地址是真實的,對任何地址不加限制地發往內存。

指令的操作數,可以是寄存器、內存地址、常數,其實通常情況下是寄存器,AX、CX 就是 x86 CPU 中的寄存器。

下面我們就去看看 x86? CPU 在實模式下的寄存器。表中每個寄存器都是 16 位的。

特別注意段寄存器(CS,DS,ES,SS)分別指代碼段寄存器,數據段寄存器,輔助段寄存器,堆棧段寄存器

雖然有了寄存器,但是數據和指令都是存放在內存中的。通常情況下,需要把數據裝載進寄存器中才能操作,還要有獲取指令的動作,這些都要訪問內存才行,而我們知道訪問內存靠的是地址值。

上面就是所謂的分段內存管理模型下的取指和內存訪問的方法,所有的內存地址都是由段寄存器左移 4 位,再加上一個通用寄存器中的值或者常數形成地址,然后由這個地址去訪問內存。

其中代碼段是由CS和IP確定的, 而堆棧是由SS和SP段確定

data SEGMENT ;定義一個數據段存放Hello World!hello  DB 'Hello World!$' ;注意要以$結束
data ENDS
code SEGMENT ;定義一個代碼段存放程序指令ASSUME CS:CODE,DS:DATA ;告訴匯編程序,DS指向數據段,CS指向代碼段
start:MOV AX,data  ;將data段首地址賦值給AX                MOV DS,AX    ;將AX賦值給DS,使DS指向data段LEA DX,hello ;使DX指向hello首地址MOV AH,09h   ;給AH設置參數09H,AH是AX高8位,AL是AX低8位,其它類似INT 21h      ;執行DOS中斷輸出DS指向的DX指向的字符串helloMOV AX,4C00h ;給AX設置參數4C00hINT 21h      ;調用4C00h號功能,結束程序
code ENDS
END start

?LEA 是取地址指令,MOV 是數據傳輸指令,就是 INT 中斷你可能還不太明白,下面我們就來研究它。

中斷即中止執行當前程序,轉而跳轉到另一個特定的地址上,去運行特定的代碼。在實模式下它的實現過程是先保存 CS 和 IP 寄存器,然后裝載新的 CS 和 IP 寄存器,那么中斷是如何產生的呢?

第一種情況是,中斷控制器給 CPU 發送了一個電子信號,CPU 會對這個信號作出應答。隨后中斷控制器會將中斷號發送給 CPU,這是硬件中斷。第二種情況就是 CPU 執行了 INT 指令,這個指令后面會跟隨一個常數,這個常數即是軟中斷號。這種情況是軟件中斷。

為了實現中斷,就需要在內存中放一個中斷向量表,這個表的地址和長度由 CPU 的特定寄存器 IDTR 指向。實模式下,表中的一個條目由代碼段地址和段內偏移組成,如下圖所示。

有了中斷號以后,CPU 就能根據 IDTR 寄存器中的信息,計算出中斷向量中的條目,進而裝載 CS(裝入代碼段基地址)、IP(裝入代碼段內偏移)寄存器,最終響應中斷。

2.保護模式

保護模式相比于實模式,增加了一些控制寄存器和段寄存器,擴展通用寄存器的位寬,所有的通用寄存器都是 32 位的,還可以單獨使用低 16 位,這個低 16 位又可以拆分成兩個 8 位寄存器,如下表。

為了區分哪些指令(如 in、out、cli)和哪些資源(如寄存器、I/O 端口、內存地址)可以被訪問,CPU 實現了特權級。特權級分為 4 級,R0~R3,每個特權級執行指令的數量不同,R0 可以執行所有指令,R1、R2、R3 依次遞減,它們只能執行上一級指令數量的子集。而內存的訪問則是靠后面所說的段描述符和特權級相互配合去實現的。如下圖.

目前為止,內存還是分段模型,要對內存進行保護,就可以轉換成對段的保護。

由于 CPU 的擴展導致了 32 位的段基地址和段內偏移,還有一些其它信息,所以 16 位的段寄存器肯定放不下。放不下就要找內存借空間,然后把描述一個段的信息封裝成特定格式的段描述符,放在內存中,其格式如下。

一個段描述符有 64 位 8 字節數據,里面包含了段基地址、段長度、段權限、段類型(可以是系統段、代碼段、數據段)、段是否可讀寫,可執行等。雖然數據分布有點亂,這是由于歷史原因造成的。

多個段描述符在內存中形成全局段描述符表,該表的基地址和長度由 CPU 的 GDTR 寄存器指示。如下圖所示。

段寄存器中不再存放段基地址,而是具體段描述符的索引,訪問一個內存地址時,段寄存器中的索引首先會結合 GDTR 寄存器找到內存中的段描述符,再根據其中的段信息判斷能不能訪問成功。

如果你認為 CS、DS、ES、SS、FS、GS 這些段寄存器,里面存放的就是一個內存段的描述符索引,那你可就草率了,其實它們是由影子寄存器、段描述符索引、描述符表索引、權限級別組成的。如下圖所示

影子寄存器是靠硬件來操作的,對系統程序員不可見,是硬件為了減少性能損耗而設計的一個段描述符的高速緩存,不然每次內存訪問都要去內存中查表,那性能損失是巨大的,影子寄存器也正好是 64 位,里面存放了 8 字節段描述符數據。

通常情況下,CS 和 SS 中 RPL 就組成了 CPL(當前權限級別),所以常常是 RPL=CPL,進而 CPL 就表示發起訪問者要以什么權限去訪問目標段,當 CPL 大于目標段 DPL 時,則 CPU 禁止訪問,只有 CPL 小于等于目標段 DPL 時才能訪問。

3.保護模式中斷

實模式下 CPU 不需要做權限檢查,所以它可以直接通過中斷向量表中的值裝載 CS:IP 寄存器就好了。

而保護模式下的中斷要權限檢查,還有特權級的切換,所以就需要擴展中斷向量表的信息,即每個中斷用一個中斷門描述符來表示,也可以簡稱為中斷門,中斷門描述符依然有自己的格式,如下圖所示。

同樣的,保護模式要實現中斷,也必須在內存中有一個中斷向量表,同樣是由 IDTR 寄存器指向,只不過中斷向量表中的條目變成了中斷門描述符,如下圖所示

產生中斷后,CPU 首先會檢查中斷號是否大于最后一個中斷門描述符,x86 CPU 最大支持 256 個中斷源(即中斷號:0~255),然后檢查描述符類型(是否是中斷門或者陷阱門)、是否為系統描述符,是不是存在于內存中。

接著,檢查中斷門描述符中的段選擇子指向的段描述符。

保護模式下中斷過程: 對于保護模式下的中斷,如果中斷號在0-255。首先通過IDTR和中斷號找到中斷門描述符,根據中斷門描述符屬性部分中的DPL來判斷當前權限是否能執行該中斷。如果CPL<=DPL,則允許通過段選擇子和段偏移訪問對應的段。 接著根據段選擇子可以在GDTR或LDTR中找到對應段的描述符。訪問段首先需要檢查段選擇子中的DPL,如果CPL=DPL則可以直接訪問;如果CPL>DPL則需要切換權限才能進一步訪問,例如從用戶態切換到內核態,此時會從TSS中加載具體權限的相應棧寄存器,切換棧運行環境后才可以繼續訪問。所謂訪問段就是將對應段的段選擇子和段內偏移加載到對應寄存器(CS、EIP),然后按序取址執行即可。執行完后會恢復到原來的權限狀態。 上述涉及到保護模式下的權限問題,什么時候能跨權限執行? ① 訪問高權限的一致代碼段(例如共享的,不訪問保護資源的代碼);② 通過合法的權限切換手段(例如中斷、異常、系統調用等)

4.切換到保護模式

x86 CPU 在第一次加電和每次 reset 后,都會自動進入實模式,要想進入保護模式,就需要程序員寫代碼實現從實模式切換到保護模式。切換到保護模式的步驟如下。

第一步,準備全局段描述符表,代碼如下。

GDT_START:
knull_dsc: dq 0
kcode_dsc: dq 0x00cf9e000000ffff
kdata_dsc: dq 0x00cf92000000ffff
GDT_END:
GDT_PTR:
GDTLEN  dw GDT_END-GDT_START-1
GDTBASE  dd GDT_START

第二步,加載設置 GDTR 寄存器,使之指向全局段描述符表。

lgdt [GDT_PTR]

第三步,設置 CR0 寄存器,開啟保護模式。

;開啟 PE
mov eax, cr0
bts eax, 0                      ; CR0.PE =1
mov cr0, eax         

第四步,進行長跳轉,加載 CS 段寄存器,即段選擇子。因為在剛進入保護模式下, 原來的段寄存器信息還殘留在,而這些數據在保護模式下是沒有用的, 所以需要長跳轉來清空指令流水線,使CPU重新加載信息

jmp dword 0x8 :_32bits_mode ;_32bits_mode為32位代碼標號即段偏移

接下來,CPU 發現了 CRO 寄存器第 0 位的值是 1,就會按 GDTR 的指示找到全局描述符表,然后根據索引值 8,把新的段描述符信息加載到 CS 影子寄存器,當然這里的前提是進行一系列合法的檢查。到此為止,CPU 真正進入了保護模式,CPU 也有了 32 位的處理能力。

5.長模式

長模式又名 AMD64,因為這個標準是 AMD 公司最早定義的,它使 CPU 在現有的基礎上有了 64 位的處理能力,既能完成 64 位的數據運算,也能尋址 64 位的地址空間

長模式相比于保護模式,增加了一些通用寄存器,并擴展通用寄存器的位寬,所有的通用寄存器都是 64 位,還可以單獨使用低 32 位。這個低 32 位可以拆分成一個低 16 位寄存器,低 16 位又可以拆分成兩個 8 位寄存器,如下表。

長模式依然具備保護模式絕大多數特性,如特權級和權限檢查。相同的部分就不再重述了,這里只會說明長模式和保護模式下的差異。下面我們來看看長模式下段描述的格式,如下圖所示。

在長模式下,CPU 不再對段基址和段長度進行檢查,只對 DPL 進行相關的檢查,這個檢查流程和保護模式下一樣。

在長模式(64 位模式)中,x86 架構對段機制進行了根本性簡化:

  • 段基地址:所有段寄存器(CS、DS、ES、SS 等)的基地址固定為 0
  • 段界限:所有段的界限固定為最大值(0xFFFFFFFFFFFFFFFF)。
  • 段描述符:仍然存在,但僅用于權限檢查(如 CPL、DPL)和內存類型標識(如代碼段 / 數據段)。

這種設計使得段機制不再參與地址計算,而是由RIP 寄存器直接提供線性地址,就像平坦模式一樣。

在長模式下,RIP 寄存器的值(或內存操作數的有效地址)直接作為 MMU 的輸入虛擬地址

下面我們來寫一個長模式下的段描述符表,加深一下理解,如下所示.

ex64_GDT:
null_dsc:  dq 0
;第一個段描述符CPU硬件規定必須為0
c64_dsc:dq 0x0020980000000000  ;64位代碼段
;無效位填0
;D/B=0,L=1,AVL=0 
;P=1,DPL=0,S=1
;T=1,C=0,R=0,A=0
d64_dsc:dq 0x0000920000000000  ;64位數據段
;無效位填0
;P=1,DPL=0,S=1
;T=0,C/E=0,R/W=1,A=0
eGdtLen   equ $ - null_dsc  ;GDT長度
eGdtPtr:dw eGdtLen - 1  ;GDT界限dq ex64_GDT

6.長模式中斷

保護模式下為了實現對中斷進行權限檢查,實現了中斷門描述符,在中斷門描述符中存放了對應的段選擇子和其段內偏移,還有 DPL 權限,如果權限檢查通過,則用對應的段選擇子和其段內偏移裝載 CS:EIP 寄存器。如果你還記得中斷門描述符,就會發現其中的段內偏移只有 32 位,但是長模式支持 64 位內存尋址,所以要對中斷門描述符進行修改和擴展,下面我們就來看看長模式下的中斷門描述符的格式,如下圖所示。

首先為了支持 64 位尋址中斷門描述符在原有基礎上增加 8 字節,用于存放目標段偏移的高 32 位值。其次,目標代碼段選擇子對應的代碼段描述符必須是 64 位的代碼段。最后其中的 IST 是 64 位 TSS 中的 IST 指針,因為我們不使用這個特性,所以不作詳細介紹。

7.切換到長模式

我們既可以從實模式直接切換到長模式,也可以從保護模式切換長模式。切換到長模式的步驟如下。第一步,準備長模式全局段描述符表。

ex64_GDT:
null_dsc:  dq 0
;第一個段描述符CPU硬件規定必須為0
c64_dsc:dq 0x0020980000000000  ;64位代碼段
d64_dsc:dq 0x0000920000000000  ;64位數據段
eGdtLen   equ $ - null_dsc  ;GDT長度
eGdtPtr:dw eGdtLen - 1  ;GDT界限dq ex64_GDT

第二步,準備長模式下的 MMU 頁表,這個是為了開啟分頁模式,切換到長模式必須要開啟分頁,想想看,長模式下已經不對段基址和段長度進行檢查了,那么內存地址空間就得不到保護了。而長模式下內存地址空間的保護交給了 MMU,MMU 依賴頁表對地址進行轉換,頁表有特定的格式存放在內存中,其地址由 CPU 的 CR3 寄存器指向。

mov eax, cr4
bts eax, 5   ;CR4.PAE = 1
mov cr4, eax ;開啟 PAE
mov eax, PAGE_TLB_BADR ;頁表物理地址
mov cr3, eax

第三步,加載 GDTR 寄存器,使之指向全局段描述表:

lgdt [eGdtPtr]

第四步,開啟長模式,要同時開啟保護模式和分頁模式,在實現長模式時定義了 MSR 寄存器,需要用專用的指令 rdmsr、wrmsr 進行讀寫,IA32_EFER 寄存器的地址為 0xC0000080,它的第 8 位決定了是否開啟長模式,MSR是CPU的一組64位寄存器,可以分別通過RDMSR和WRMSR 兩條指令進行讀和寫的操作,前提要在ECX中寫入MSR的地址。 對于RDMSR 指令,將會返回相應的MSR 中64bit 信息到(EDX:EAX)寄存器中;對于WRMSR 指令,把要寫入的信息存入(EDX:EAX)中,執行寫指令后,即可將相應的信息存入ECX 指定的MSR 中。MSR 的指令必須執行在level 0 或實模式下。

;開啟 64位長模式
mov ecx, IA32_EFER
rdmsr
bts eax, 8  ;IA32_EFER.LME =1
wrmsr
;開啟 保護模式和分頁模式
mov eax, cr0
bts eax, 0    ;CR0.PE =1
bts eax, 31
mov cr0, eax 

第五步,進行跳轉,加載 CS 段寄存器,刷新其影子寄存器。

jmp 08:entry64 ;entry64為程序標號即64位偏移地址

切換到長模式和切換保護模式的流程差不多,只是需要準備的段描述符有所區別,還有就是要注意同時開啟保護模式和分頁模式。原因在上面已經說明了。

參考:LMOS 操作系統

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/87864.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/87864.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/87864.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java設計模式之行為型模式(策略模式)介紹與說明

一、策略模式簡介 策略模式&#xff08;Strategy Pattern&#xff09;是一種行為型設計模式&#xff0c;它定義了一系列算法&#xff0c;并將每個算法封裝起來&#xff0c;使它們可以相互替換&#xff0c;且算法的變化不會影響使用算法的客戶。策略模式讓算法獨立于使用它的客…

【BIOS+MBR 微內核手寫實現】

本文基于BIOS+MBR的架構,從四部分講解微內核是如何實現的: 1)搭建微內核編譯調試環境 2)梳理微內核的代碼結構:偽指令講解 3)手寫實現微內核框架,輸出簡單的字符串 4)講解微內核啟動階段的具體運行過程 先完成內核工程創建,如下圖 我們這里使用nasm風格的匯編編寫,…

從C/C++遷移到Go:內存管理思維轉變

一、引言 在當今高速發展的軟件開發世界中&#xff0c;語言遷移已成為技術進化的常態。作為一名曾經的C/C開發者&#xff0c;我經歷了向Go語言轉變的全過程&#xff0c;其中最大的認知挑戰來自內存管理模式的根本性差異。 我記得第一次接觸Go項目時的困惑&#xff1a;沒有析構函…

正確設置 FreeRTOS 與 STM32 的中斷優先級

在裸機開發&#xff08;非 RTOS&#xff09;時&#xff0c;大多數 STM32 外設的中斷優先級通常不需要手動配置&#xff0c;原因如下&#xff1a; ? 裸機開發中默認中斷優先級行為 特點說明默認中斷優先級為 0如果你不設置&#xff0c;STM32 HAL 默認設置所有外設中斷為 0&…

EasyExcel之SheetWriteHandler:解鎖Excel寫入的高階玩法

引言在 EasyExcel 強大的功能體系中&#xff0c;SheetWriteHandler 接口是一個關鍵的組成部分。它允許開發者在寫入 Excel 的 Sheet 時進行自定義處理&#xff0c;為實現各種復雜的業務需求提供了強大的支持。通過深入了解和運用 SheetWriteHandler 接口&#xff0c;我們能夠更…

Python單例模式魔法方法or屬性

1.單例模式概念定義:單例模式(Singleton Pattern)是一種創建型設計模式&#xff0c;它確保一個類只能有一個實例&#xff0c;并提供一個全局訪問點來獲取該實例。這種模式在需要控制資源訪問、配置管理或協調系統操作時特別有用。核心特點:私有構造函數&#xff1a;防止外部通過…

【Kubernetes系列】Kubernetes 資源請求(Requests)

博客目錄 引言一、資源請求的基本概念1.1 什么是資源請求1.2 請求與限制的區別 二、CPU 請求的深入解析2.1 CPU 請求的單位與含義2.2 CPU 請求的調度影響2.3 CPU 請求與限制的關系 三、內存請求的深入解析3.1 內存請求的單位與含義3.2 內存請求的調度影響3.3 內存請求的特殊性 …

大型語言模型中的自動化思維鏈提示

摘要 大型語言模型&#xff08;LLMs&#xff09;能夠通過生成中間推理步驟來執行復雜的推理任務。為提示演示提供這些步驟的過程被稱為思維鏈&#xff08;CoT&#xff09;提示。CoT提示有兩種主要范式。一種使用簡單的提示語&#xff0c;如“讓我們一步一步思考”&#xff0c;…

Private Set Generation with Discriminative Information(2211.04446v1)

1. 遇到什么問題&#xff0c;解決了什么遇到的問題現有差分隱私生成模型受限于高維數據分布建模的復雜性&#xff0c;合成樣本實用性不足。深度生成模型訓練依賴大量數據&#xff0c;加入隱私約束后更難優化&#xff0c;且不保證下游任務&#xff08;如分類&#xff09;的最優解…

C++編程語言入門指南

一、C語言概述 C是由丹麥計算機科學家Bjarne Stroustrup于1979年在貝爾實驗室開發的一種靜態類型、編譯式、通用型編程語言。最初被稱為"C with Classes"(帶類的C)&#xff0c;1983年更名為C。它既具有高級語言的抽象特性&#xff0c;又保留了底層硬件操作能力&…

ZED相機與Foxglove集成:加速機器人視覺調試效率的實用方案

隨著機器人技術的發展&#xff0c;實時視覺數據流的高效傳輸和可視化成為提升系統性能的重要因素。通過ZED相機&#xff08;包括ZED 2i和ZED X&#xff09;與Foxglove Studio平臺的結合&#xff0c;開發者能夠輕松訪問高質量的2D圖像、深度圖和點云數據&#xff0c;從而顯著提高…

目標檢測新紀元:DETR到Mamba實戰解析

&#x1f680;【實戰分享】目標檢測的“后 DE?”時代&#xff1a;DETR/DINO/RT-DETR及新型骨干網絡探索&#xff08;含示例代碼&#xff09; 目標檢測從 YOLO、Faster R-CNN 到 Transformer 結構的 DETR&#xff0c;再到 DINO、RT-DETR&#xff0c;近兩年出現了許多新趨勢&am…

【IOS】XCode創建firstapp并運行(成為IOS開發者)

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 這篇文章主要介紹XCode創建firstapp并運行 學其所用&#xff0c;用其所學。——梁啟超 歡迎來到我的博客&#xff0c;一起學習&#xff0c;共同進步。 喜歡的朋友可以關注一下&#xff0c;下次更新不迷路…

class類和style內聯樣式的綁定 + 事件處理 + uniapp創建自定義頁面模板

目錄 一.class類的綁定 1.靜態編寫 2.動態編寫 二.style內聯樣式的綁定 三.事件處理 1.案例1 2.案例2 四.uniapp創建自定義頁面模板 1.為什么要這么做&#xff1f; 2.步驟 ①打開新建頁面的界面 ②在彈出的目錄下&#xff0c;新建模板文件 ③用HBuilderX打開該模板…

android 卡頓和丟幀區別

Android 卡頓&#xff08;Jank&#xff09;與丟幀&#xff08;Frame Drop&#xff09;的核心區別在于問題本質與用戶感知&#xff0c;以下是分層解析&#xff1a; ? 一、本質差異 維度卡頓&#xff08;Jank&#xff09;丟幀&#xff08;Frame Drop&#xff09;定義用戶可感知…

【python實用小腳本-125】基于 Python 的 Gmail 郵件發送工具:實現高效郵件自動化

引言 在現代辦公和開發環境中&#xff0c;郵件通信是一種重要的溝通方式。自動化發送郵件可以大大提高工作效率&#xff0c;例如發送通知、報告或文件。本文將介紹一個基于 Python 的 Gmail 郵件發送工具&#xff0c;它能夠通過 Gmail 的 SMTP 服務器發送郵件&#xff0c;并支持…

gateway斷言配置詳解

一、Predicate - 斷? 1、簡單用法 spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After2017-01-20T17:42:47.789-07:00[America/Denver] 2、自定義斷言 新建類VipRoutePredicateFactory&#xff0c;注意VipRoutePredicateFactory名字…

基于大模型的尿毒癥全流程預測與診療方案研究報告

目錄 一、引言 1.1 研究背景與意義 1.2 研究目的與方法 1.3 國內外研究現狀 二、尿毒癥相關理論基礎 2.1 尿毒癥的定義、病因與發病機制 2.2 尿毒癥的癥狀與診斷標準 2.3 尿毒癥的治療方法概述 三、大模型技術原理與應用 3.1 大模型的基本概念與發展歷程 3.2 大模型…

裸金屬服務器租用平臺-青蛙云

企業對服務器性能與靈活性的要求與日俱增。青蛙云M-啟強裸金屬服務器租用平臺應運而生&#xff0c;為企業提供了一種兼具物理機性能和云計算彈性的解決方案。裸金屬服務器租用平臺的優勢?(一)高配性能&#xff0c;無虛擬化開銷?裸金屬服務器直接運行在物理硬件之上&#xff0…

[Terence Tao訪談] AlphaProof系統 | AI嗅覺 | 研究生學習 | 龐加萊猜想(高維) | 復雜問題簡單化

玩這些有趣的東西。通常情況下什么也得不到&#xff0c;你必須學會說&#xff1a;“好吧&#xff0c;再試一次&#xff0c;什么都沒發生&#xff0c;我會繼續前進。” DeepMind的AlphaProof系統 Q&#xff1a;DeepMind的AlphaProof系統是通過強化學習訓練的&#xff0c;使用的…