計算機的工作模式
如上圖:
- CPU(Central Processing Unit,中央處理器),計算機最核心部件
- 總線(Bus),用於CPU 和其他設備連接,分爲 **地址總線(Address Bus)**和 數據總線(Data Bus)
- 內存(Memory), 保存計算任務中產生的中間結果
- 總線上其他設備,顯卡會連接顯示器、磁盤控制器會連接硬盤、USB 控制器會連接鍵盤和鼠標等等。
- CPU 和內存是完成計算任務的核心組件
地址總線的位數,決定了能訪問的地址範圍到底有多廣
數據總線的位數,決定了一次能拿多少個數據進來
CPU 和內存是如何配合工作的
CPU包括三個部分,運算單元、數據單元和控制單元
- 運算單元:只管算,不知道應該算哪些數據,運算結果應該放在哪裏。
- 數據單元:CPU 內部的緩存和寄存器組,空間小但速度飛快,可以暫時存放數據和運算結果。
- 控制單元:是一個統一的指揮中心,它可以獲得下一條指令,然後執行這條指令。這個指令會指導運算單元取出數據單元中的某幾個數據,計算出個結果,然後放在數據單元的某個地方。
一條指令的執行
- CPU 的控制單元裏面有一個指令指針寄存器,存放的是下一條指令在內存中的地址。
- 控制單元會不停地將內存代碼段的指令拿進來,先放入指令寄存器。
- 指令分兩部分,一部分是做什麼操作,例如是加法還是位移;一部分是操作哪些數據。
- 執行這條指令,就要把第一部分交給運算單元,第二部分交給數據單元。
- 數據單元根據數據的地址,從內存數據段裏讀到數據寄存器裏;運算單元做完運算,產生的結果會暫存在數據單元的數據寄存器裏;最後,通過指令將數據寫回內存中的數據段。
8086 的原理
8086 處理器是x86 中最經典的一款處理器,現在操作系統中的很多特性都和它有關,並且一直保持兼容。
數據單元
8 個 16 位的通用寄存器
- AX、BX、CX、DX、SP、BP、SI、DI
- AX、BX、CX、DX 可以分成兩個 8 位的寄存器來使用
- AH、AL、BH、BL、CH、CL、DH、DL,其中 H 就是 High(高位),L 就是 Low(低位)的意思。
控制單元
IP 寄存器就是指令指針寄存器(Instruction Pointer Register)
四個 16 位的段寄存器,分別是 CS、DS、SS、ES。
- CS 就是代碼段寄存器(Code Segment Register),通過它可以找到代碼在內存中的位置
- DS 是數據段的寄存器,通過它可以找到數據在內存中的位置
- SS 是棧寄存器(Stack Register),棧,一個特殊的數據結構,後進先出的原則,函數調用相關的操作,都與棧緊密相關
- ES 附加段寄存器(Extra Segment)
如何將內存數據加載到通用寄存器中呢?
起始地址+偏移量(Offset)的方式
CS 和 DS 中都存放着一個段的起始地址
偏移量(Offset):代碼段的偏移量在 IP 寄存器中;數據段的偏移量會放在通用寄存器中
“起始地址 *16+ 偏移量”:
CS 和 DS 都是 16 位的,IP 寄存器和通用寄存器都是 16 位的,偏移量也是 16 位的,8086 的地址總線地址是 20 位,通過 “起始地址 *16+ 偏移量” 湊夠20位。20 位地址總線的 8086 ,能夠區分出的地址也就 2^20=1M
32 位處理器
32 位處理器中,有 32 根地址總線,可以訪問 2^32=4G 的內存,之前8086的模式行不通但又不能完全放棄,因爲已經有很多公司的軟硬件都是基於8086這一架構,只能進行兼容。
那麼,如何保持兼容?
通用寄存器:將 8 個 16 位的擴展到 8 個 32,保留16 位的和 8 位的使用方式
指令指針寄存器 IP:擴展成 32 位的,同樣也兼容 16 位
段寄存器(Segment Register):有些不兼容
- CS、SS、DS、ES 仍然是 16 位的,但是不再是段的起始地址,而是段選擇子
- 段的起始地址放在內存的某個地方,用表格存放,其中一項一項是段描述符(Segment Descriptor),通過段選擇子確定是哪一項
- 從段寄存器直接拿到的段起始地址 -> 先間接地從段寄存器找到表格中的一項,再從表格中的一項中拿到段起始地址
段寄存器的不兼容,就有了32 位的系統架構**實模式(Real Pattern)和保護模式(Protected Pattern)**來就解決兼容問題。當系統剛剛啓動的時候,CPU 是處於實模式的,這個時候和原來8086的模式是兼容的,進行一系列的操作,然後切換到保護模式,使用全部的32根地址總線。
參考資料:
趣談Linux操作系統(極客時間)鏈接:
http://gk.link/a/10iXZ
歡迎大家來一起交流學習