0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

通過(guò)了解寄存器的功能與作用去揭秘CPU核心技術(shù)

FPGA之家 ? 來(lái)源:CSDN技術(shù)社區(qū) ? 作者:編程技術(shù)宇宙 ? 2021-04-27 14:32 ? 次閱讀

序言

前段時(shí)間,我連續(xù)寫了十來(lái)篇CPU底層系列技術(shù)故事文章,有不少讀者私信我讓我寫一下CPU的寄存器

寄存器這個(gè)太多太復(fù)雜,不適合寫故事,拖了很久,總算是寫完了,這篇文章就來(lái)詳細(xì)聊聊x86/x64架構(gòu)的CPU中那些紛繁復(fù)雜的寄存器們。

長(zhǎng)文預(yù)警,時(shí)速較快,請(qǐng)系好安全帶~起飛~

自1946年馮·諾伊曼領(lǐng)導(dǎo)下誕生的世界上第一臺(tái)通用電子計(jì)算機(jī)ENIAC至今,計(jì)算機(jī)技術(shù)已經(jīng)發(fā)展了七十多載。

從當(dāng)初專用于數(shù)學(xué)計(jì)算的龐然大物,到后來(lái)大型機(jī)服務(wù)器時(shí)代,從個(gè)人微機(jī)技術(shù)蓬勃發(fā)展,到互聯(lián)網(wǎng)浪潮席卷全球,再到移動(dòng)互聯(lián)網(wǎng)、云計(jì)算日新月異的當(dāng)下,計(jì)算機(jī)變的形態(tài)各異,無(wú)處不在。

這七十多年中,出現(xiàn)了數(shù)不清的編程語(yǔ)言,通過(guò)這些編程語(yǔ)言,又開(kāi)發(fā)了無(wú)數(shù)的應(yīng)用程序。

可無(wú)論什么樣的應(yīng)用程序,什么樣的編程語(yǔ)言,最終的程序邏輯都是要交付給CPU去執(zhí)行實(shí)現(xiàn)的(當(dāng)然這里有些不嚴(yán)謹(jǐn),除了CPU,還有協(xié)處理器、GPU等等)。所以了解和學(xué)習(xí)CPU的原理都是對(duì)計(jì)算機(jī)基礎(chǔ)知識(shí)的夯實(shí)大有裨益。

在七十多年的漫長(zhǎng)歷程中,也涌現(xiàn)了不少架構(gòu)的CPU。

MIPS

PowerPC

x86/x64

IA64

ARM

······

這篇文章就以市場(chǎng)應(yīng)用最為廣泛的x86-x64架構(gòu)為目標(biāo),通過(guò)學(xué)習(xí)了解它內(nèi)部的100個(gè)寄存器功能作用,來(lái)串聯(lián)闡述CPU底層工作原理。

通過(guò)這篇文章,你將了解到:

CPU指令執(zhí)行原理

內(nèi)存尋址技術(shù)

軟件調(diào)試技術(shù)原理

中斷與異常處理

系統(tǒng)調(diào)用

CPU多任務(wù)技術(shù)

什么是寄存器?

寄存器是CPU內(nèi)部用來(lái)存放數(shù)據(jù)的一些小型存儲(chǔ)區(qū)域,用來(lái)暫時(shí)存放參與運(yùn)算的數(shù)據(jù)和運(yùn)算結(jié)果以及一些CPU運(yùn)行需要的信息。

x86架構(gòu)CPU走的是復(fù)雜指令集(CISC) 路線,提供了豐富的指令來(lái)實(shí)現(xiàn)強(qiáng)大的功能,與此同時(shí)也提供了大量寄存器來(lái)輔助功能實(shí)現(xiàn)。這篇文章將覆蓋下面這些寄存器:

通用寄存器

標(biāo)志寄存器

指令寄存器

段寄存器

控制寄存器

調(diào)試寄存器

描述符寄存器

任務(wù)寄存器

MSR寄存器

通用寄存器

首當(dāng)其沖的是通用寄存器,這些的寄存器是程序執(zhí)行代碼最最常用,也最最基礎(chǔ)的寄存器,程序執(zhí)行過(guò)程中,絕大部分時(shí)間都是在操作這些寄存器來(lái)實(shí)現(xiàn)指令功能。

所謂通用,即這些寄存器CPU沒(méi)有特殊的用途,交給應(yīng)用程序“隨意”使用。注意,這個(gè)隨意,我打了引號(hào),對(duì)于有些寄存器,CPU有一些潛規(guī)則,用的時(shí)候要注意。

eax: 通常用來(lái)執(zhí)行加法,函數(shù)調(diào)用的返回值一般也放在這里面

ebx: 數(shù)據(jù)存取

ecx: 通常用來(lái)作為計(jì)數(shù)器,比如for循環(huán)

edx: 讀寫I/O端口時(shí),edx用來(lái)存放端口號(hào)

esp: 棧頂指針,指向棧的頂部

ebp: 棧底指針,指向棧的底部,通常用ebp+偏移量的形式來(lái)定位函數(shù)存放在棧中的局部變量

esi: 字符串操作時(shí),用于存放數(shù)據(jù)源的地址

edi: 字符串操作時(shí),用于存放目的地址的,和esi兩個(gè)經(jīng)常搭配一起使用,執(zhí)行字符串的復(fù)制等操作

在x64架構(gòu)中,上面的通用寄存器都擴(kuò)展成為64位版本,名字也進(jìn)行了升級(jí)。當(dāng)然,為了兼容32位模式程序,使用上面的名字仍然是可以訪問(wèn)的,相當(dāng)于訪問(wèn)64位寄存器的低32位。

raxrbxrcxrdxrsprbprsirdi

除了擴(kuò)展原來(lái)存在的通用寄存器,x64架構(gòu)還引入了8個(gè)新的通用寄存器:

r8-r15

在原來(lái)32位時(shí)代,函數(shù)調(diào)用時(shí),那個(gè)時(shí)候通用寄存器少,參數(shù)絕大多數(shù)時(shí)候是通過(guò)線程的棧來(lái)進(jìn)行傳遞(當(dāng)然也有使用寄存器傳遞的,比如著名的C++ this指針使用ecx寄存器傳遞,不過(guò)能用的寄存器畢竟不多)。

進(jìn)入x64時(shí)代,寄存器資源富裕了,參數(shù)傳遞絕大多數(shù)都是用寄存器來(lái)傳了。寄存器傳參的好處是速度快,減少了對(duì)內(nèi)存的讀寫次數(shù)。

當(dāng)然,具體使用棧還是用寄存器傳參數(shù),這個(gè)不是編程語(yǔ)言決定的,而是編譯器在編譯生成CPU指令時(shí)決定的,如果編譯器非要在x64架構(gòu)CPU上使用線程棧來(lái)傳參那也不是不行,這個(gè)對(duì)高級(jí)語(yǔ)言是無(wú)感知的。

標(biāo)志寄存器

標(biāo)志寄存器,里面有眾多標(biāo)記位,記錄了CPU執(zhí)行指令過(guò)程中的一系列狀態(tài),這些標(biāo)志大都由CPU自動(dòng)設(shè)置和修改:

CF 進(jìn)位標(biāo)志

PF 奇偶標(biāo)志

ZF 零標(biāo)志

SF 符號(hào)標(biāo)志

OF 補(bǔ)碼溢出標(biāo)志

TF 跟蹤標(biāo)志

IF 中斷標(biāo)志

······

0b86b5e6-a67f-11eb-aece-12bb97331649.png

在x64架構(gòu)下,原來(lái)的eflags寄存器升級(jí)為64位的rflags,不過(guò)其高32位并沒(méi)有新增什么功能,保留為將來(lái)使用。

指令寄存器

eip: 指令寄存器可以說(shuō)是CPU中最最重要的寄存器了,它指向了下一條要執(zhí)行的指令所存放的地址,CPU的工作其實(shí)就是不斷取出它指向的指令,然后執(zhí)行這條指令,同時(shí)指令寄存器繼續(xù)指向下面一條指令,如此不斷重復(fù),這就是CPU工作的基本日常。

而在漏洞攻擊中,黑客想盡辦法費(fèi)盡心機(jī)都想要修改指令寄存器的地址,從而能夠執(zhí)行惡意代碼。

同樣的,在x64架構(gòu)下,32位的eip升級(jí)為64位的rip寄存器。

段寄存器

段寄存器與CPU的內(nèi)存尋址技術(shù)緊密相關(guān)。

早在16位的8086CPU時(shí)代,內(nèi)存資源寶貴,CPU使用分段式內(nèi)存尋址技術(shù):

0bd624b4-a67f-11eb-aece-12bb97331649.png

16位的寄存器能尋址的范圍是64KB,通過(guò)引入段的概念,將內(nèi)存空間劃分為不同的區(qū)域:分段,通過(guò)段基址+段內(nèi)偏移段方式來(lái)尋址。

這樣一來(lái),段的基地址保存在哪里呢?8086CPU專門設(shè)置了幾個(gè)段寄存器用來(lái)保存段的基地址,這就是段寄存器段的由來(lái)。

段寄存器也是16位的。

段寄存器有下面6個(gè),前面4個(gè)是早期16位模式就引入了,到了32位時(shí)代,又新增了fs和gs兩個(gè)段寄存器。

cs: 代碼段

ds: 數(shù)據(jù)段

ss: 棧段

es: 擴(kuò)展段

fs: 數(shù)據(jù)段

gs: 數(shù)據(jù)段

段寄存器里面存儲(chǔ)的內(nèi)容與CPU當(dāng)前工作的內(nèi)存尋址模式緊密相關(guān)。

當(dāng)CPU處于16位實(shí)地址模式下時(shí),段寄存器存儲(chǔ)段的基地址,尋址時(shí),將段寄存器內(nèi)容左移4位(乘以16)得到段基地址+段內(nèi)偏移得到最終的地址。

當(dāng)CPU工作于保護(hù)模式下,段寄存器存儲(chǔ)的內(nèi)容不再是段基址了,此時(shí)的段寄存器中存放的是段選擇子,用來(lái)指示當(dāng)前這個(gè)段寄存器“指向”的是哪個(gè)分段。

注意我這里的指向打了引號(hào),段寄存器中存儲(chǔ)的并不是內(nèi)存段的直接地址,而是段選擇子,它的結(jié)構(gòu)如下:

0be110d6-a67f-11eb-aece-12bb97331649.png

16個(gè)bit長(zhǎng)度的段寄存器內(nèi)容劃分了三個(gè)字段:

PRL: 特權(quán)請(qǐng)求級(jí),就是我們常說(shuō)的ring0-ring3四個(gè)特權(quán)級(jí)。

TI: 0表示用的是全局描述符表GDT,1表示使用的是局部描述符表LDT。

Index: 這是一個(gè)表格中表項(xiàng)的索引值,這個(gè)表格叫內(nèi)存描述符表,它的每一個(gè)表項(xiàng)都描述了一個(gè)內(nèi)存分段。

這里提到了兩個(gè)表,全局描述符表GDT和局部描述符表LDT,關(guān)于這兩個(gè)表的介紹,下面介紹描述符寄存器時(shí)再詳述,這里只需要知道,這是CPU支持分段式內(nèi)存管理需要的表格,放在內(nèi)存中,表格中的每一項(xiàng)都是一個(gè)描述符,記錄了一個(gè)內(nèi)存分段的信息。

保護(hù)模式下的段寄存器和段描述符到最后的內(nèi)存分段,通過(guò)下圖的方式聯(lián)系在一起:

0c106778-a67f-11eb-aece-12bb97331649.png

通用寄存器、段寄存器、標(biāo)志寄存器、指令寄存器,這四組寄存器共同構(gòu)成了一個(gè)基本的指令執(zhí)行環(huán)境,一個(gè)線程的上下文也基本上就是這些寄存器,在執(zhí)行線程切換的時(shí)候,就是修改它們的內(nèi)容。

0d7f784c-a67f-11eb-aece-12bb97331649.png

控制寄存器

控制寄存器是CPU中一組相當(dāng)重要的寄存器,我們知道eflags寄存器記錄了當(dāng)前運(yùn)行線程的一系列關(guān)鍵信息。

那CPU運(yùn)行過(guò)程中自身的一些關(guān)鍵信息保存在哪里呢?答案是控制寄存器!

0d8ba004-a67f-11eb-aece-12bb97331649.png

32位CPU總共有cr0-cr4共5個(gè)控制寄存器,64位增加了cr8。他們各自有不同的功能,但都存儲(chǔ)了CPU工作時(shí)的重要信息:

cr0: 存儲(chǔ)了CPU控制標(biāo)記和工作狀態(tài)

cr1: 保留未使用

cr2: 頁(yè)錯(cuò)誤出現(xiàn)時(shí)保存導(dǎo)致出錯(cuò)的地址

cr3: 存儲(chǔ)了當(dāng)前進(jìn)程的虛擬地址空間的重要信息——頁(yè)目錄地址

cr4: 也存儲(chǔ)了CPU工作相關(guān)以及當(dāng)前人任務(wù)的一些信息

cr8: 64位新增擴(kuò)展使用

其中,CR0尤其重要,它包含了太多重要的CPU信息,值得單獨(dú)關(guān)注一下:

0e70cf12-a67f-11eb-aece-12bb97331649.png

一些重要的標(biāo)記位含義如下:

PG: 是否啟用內(nèi)存分頁(yè)

AM: 是否啟用內(nèi)存對(duì)齊自動(dòng)檢查

WP: 是否開(kāi)啟內(nèi)存寫保護(hù),若開(kāi)啟,對(duì)只讀頁(yè)面嘗試寫入時(shí)將觸發(fā)異常,這一機(jī)制常常被用來(lái)實(shí)現(xiàn)寫時(shí)復(fù)制功能

PE: 是否開(kāi)啟保護(hù)模式

除了CR0,另一個(gè)值得關(guān)注的寄存器是CR3,它保存了當(dāng)前進(jìn)程所使用的虛擬地址空間的頁(yè)目錄地址,可以說(shuō)是整個(gè)虛擬地址翻譯中的頂級(jí)指揮棒,在進(jìn)程空間切換的時(shí)候,CR3也將同步切換。

調(diào)試寄存器

在x86/x64CPU內(nèi)部,還有一組用于支持軟件調(diào)試的寄存器。

調(diào)試,對(duì)于我們程序員是家常便飯,必備技能。但你想過(guò)你的程序能夠被調(diào)試背后的原理嗎?

程序能夠被調(diào)試,關(guān)鍵在于能夠被中斷執(zhí)行和恢復(fù)執(zhí)行,被中斷的地方就是我們?cè)O(shè)置的斷點(diǎn)。那程序是如何能在遇到斷點(diǎn)的時(shí)候停下來(lái)呢?

對(duì)于一些解釋執(zhí)行(PHP、Python、JavaScript)或虛擬機(jī)執(zhí)行(Java)的高級(jí)語(yǔ)言,這很容易辦到,因?yàn)樗鼈兊膱?zhí)行都在解釋器/虛擬機(jī)的掌控之中。

而對(duì)于像C、C++這樣的“底層”編程語(yǔ)言,程序代碼是直接編譯成CPU的機(jī)器指令來(lái)執(zhí)行的,這就需要CPU來(lái)提供對(duì)于調(diào)試的支持了。

對(duì)于通常的斷點(diǎn),也就是程序執(zhí)行到某個(gè)位置下就停下來(lái),這種斷點(diǎn)實(shí)現(xiàn)的方式,在x86/x64上,是利用了一條軟中斷指令:int 3來(lái)進(jìn)行實(shí)現(xiàn)的。

注意,這里的int不是指高級(jí)語(yǔ)言里面的整數(shù),而是表示interrupt中斷的意思,是一條匯編指令,int 3則表示中斷向量號(hào)為3的中斷。

在我們使用調(diào)試器下斷點(diǎn)時(shí),調(diào)試器將會(huì)把對(duì)應(yīng)位置的原來(lái)的指令替換為一個(gè)int 3指令,機(jī)器碼為0xCC。這個(gè)動(dòng)作對(duì)我們是透明的,我們?cè)谡{(diào)試器中看到的依然是原來(lái)的指令,但實(shí)際上內(nèi)存中已經(jīng)不是原來(lái)的指令了。

順便提一句,兩個(gè)0xCC是漢字【燙】的編碼,在一些編譯器里,會(huì)給線程的棧中填充大量的0xCC,如果程序出錯(cuò)的時(shí)候,我們經(jīng)常會(huì)看到很多燙燙燙出現(xiàn),就是這個(gè)原因。

0e8eb5ea-a67f-11eb-aece-12bb97331649.png

言歸正傳,CPU在執(zhí)行這條int 3指令時(shí),將自動(dòng)觸發(fā)中斷處理流程(雖然這實(shí)際上不是一個(gè)真正的中斷),CPU將取出IDTR寄存器指向的中斷描述符表IDT的第3項(xiàng),執(zhí)行里面的中斷處理函數(shù)。

而這個(gè)中斷描述符表,早在操作系統(tǒng)啟動(dòng)之初,就已經(jīng)提前安排好了,所以執(zhí)行這條指令后,操作系統(tǒng)的中斷處理函數(shù)將介入,來(lái)處理這一事件。

后面的過(guò)程就多了,簡(jiǎn)單來(lái)說(shuō),操作系統(tǒng)會(huì)把觸發(fā)這一事件的進(jìn)程凍結(jié)起來(lái),隨后將這一事件發(fā)送到調(diào)試器,調(diào)試器拿到之后就知道目標(biāo)進(jìn)程觸發(fā)斷點(diǎn)了。這個(gè)時(shí)候,咱們程序員就能通過(guò)調(diào)試器的UI交互界面或者命令行調(diào)試接口來(lái)調(diào)試目標(biāo)進(jìn)程,查看堆棧、查看內(nèi)存、變量都隨你。

如果我們要繼續(xù)運(yùn)行,調(diào)試器將會(huì)把之前修改的int 3指令給恢復(fù)回去,然后告知操作系統(tǒng):我處理完了,把目標(biāo)進(jìn)程解凍吧!

上面簡(jiǎn)單描述了一下普通斷點(diǎn)的實(shí)現(xiàn)原理?,F(xiàn)在思考一個(gè)場(chǎng)景:我們發(fā)現(xiàn)一個(gè)bug,某個(gè)全局整數(shù)型變量的值老是莫名其妙被修改,但你發(fā)現(xiàn)有很多線程,很多函數(shù)都有可能會(huì)去修改這個(gè)變量,你想找出到底誰(shuí)干的,怎么辦?

這個(gè)時(shí)候上面的普通斷點(diǎn)就沒(méi)辦法了,你需要一種新的斷點(diǎn):硬件斷點(diǎn)。

這時(shí)候就該本小節(jié)的主人公調(diào)試寄存器登場(chǎng)表演了。

0e979fa2-a67f-11eb-aece-12bb97331649.png

在x86架構(gòu)CPU內(nèi)部,提供了8個(gè)調(diào)試寄存器DR0~DR7。

DR0~DR3:這是四個(gè)用于存儲(chǔ)地址的寄存器

DR4~DR5:這兩個(gè)有點(diǎn)特殊,受前面提到的CR4寄存器中的標(biāo)志位DE位控制,如果CR4的DE位是1,則DR4、DR5是不可訪問(wèn)的,訪問(wèn)將觸發(fā)異常。如果CR4的DE位是0,則DR4和DR5將會(huì)變成DR6和DR7的別名,相當(dāng)于做了一個(gè)軟鏈接。這樣做是為了將DR4、DR5保留,以便將來(lái)擴(kuò)展調(diào)試功能時(shí)使用。

DR6:這個(gè)寄存器中存儲(chǔ)了硬件斷點(diǎn)觸發(fā)后的一些狀態(tài)信息

DR7:調(diào)試控制寄存器,這里面記錄了對(duì)DR0-DR3這四個(gè)寄存器中存儲(chǔ)地址的中斷方式(是對(duì)地址的讀,還是寫,還是執(zhí)行)、數(shù)據(jù)長(zhǎng)度(1/2/4個(gè)字節(jié))以及作用范圍等信息

通過(guò)調(diào)試器的接口設(shè)置硬件斷點(diǎn)后,CPU在執(zhí)行代碼的過(guò)程中,如果滿足條件,將自動(dòng)中斷下來(lái)。

回答前面提出的問(wèn)題,想要找出是誰(shuí)偷偷修改了全局整形變量,只需要通過(guò)調(diào)試器設(shè)置一個(gè)硬件寫入斷點(diǎn)即可。

描述符寄存器

所謂描述符,其實(shí)就是一個(gè)數(shù)據(jù)結(jié)構(gòu),用來(lái)記錄一些信息,‘描述’一個(gè)東西。把很多個(gè)描述符排列在一起,組成一個(gè)表,就成了描述符表。再使用一個(gè)寄存器來(lái)指向這個(gè)表,這個(gè)寄存器就是描述符寄存器。

在x86/x64系列CPU中,有三個(gè)非常重要的描述符寄存器,它們分別存儲(chǔ)了三個(gè)地址,指向了三個(gè)非常重要的描述符表。

gdtr: 全局描述符表寄存器,前面提到,CPU現(xiàn)在使用的是段+分頁(yè)結(jié)合的內(nèi)存管理方式,那系統(tǒng)總共有那些分段呢?這就存儲(chǔ)在一個(gè)叫全局描述符表(GDT)的表格中,并用gdtr寄存器指向這個(gè)表。這個(gè)表中的每一項(xiàng)都描述了一個(gè)內(nèi)存段的信息。

ldtr: 局部描述符表寄存器,這個(gè)寄存器和上面的gdtr一樣,同樣指向的是一個(gè)段描述符表(LDT)。不同的是,GDT是全局唯一,LDT是局部使用的,可以創(chuàng)建多個(gè),隨著任務(wù)段切換而切換(下文介紹任務(wù)寄存器會(huì)提到)。

0ea7663a-a67f-11eb-aece-12bb97331649.png

GDT和LDT中的表項(xiàng),就是段描述符,描述了一個(gè)內(nèi)存分段的信息,其結(jié)構(gòu)如下:

0eb6db1a-a67f-11eb-aece-12bb97331649.png

一個(gè)表項(xiàng)占據(jù)8個(gè)字節(jié)(32位CPU),里面存儲(chǔ)了一個(gè)內(nèi)存分段的諸多信息:基地址、大小、權(quán)限、類型等信息。

除了這兩個(gè)段描述符寄存器,還有一個(gè)非常重要的描述符寄存器:

idtr: 中斷描述符表寄存器,指向了中斷描述符表IDT,這個(gè)表的每一項(xiàng)都是一個(gè)中斷處理描述符,當(dāng)CPU執(zhí)行過(guò)程中發(fā)生了硬中斷、異常、軟中斷時(shí),將自動(dòng)從這個(gè)表中定位對(duì)應(yīng)的表項(xiàng),里面記錄了發(fā)生中斷、異常時(shí)該去哪里執(zhí)行處理函數(shù)。

0ec87f78-a67f-11eb-aece-12bb97331649.png

IDT中的表項(xiàng)稱為Gate,中文意思為門,因?yàn)檫@是應(yīng)用程序進(jìn)入內(nèi)核的主要入口。雖然表的名字叫中斷描述符表,但表中存儲(chǔ)的不全是中斷描述符,IDT中的表項(xiàng)存在三種類型,對(duì)應(yīng)三種類型的門:

任務(wù)門

陷阱門

中斷門

0ee72a90-a67f-11eb-aece-12bb97331649.png

三種描述符中都存儲(chǔ)了處理這個(gè)中斷/異常/任務(wù)時(shí)該去哪里處理的地址。三種門用途不一,其中中斷門是真正意義上的中斷,而像前面提到的調(diào)試指令int 3以及老式的系統(tǒng)調(diào)用指令int 2e/int 80都屬于陷阱門。任務(wù)門則用的較少,要了解任務(wù)門,先了解下任務(wù)寄存器。

任務(wù)寄存器現(xiàn)代操作系統(tǒng),都是支持多任務(wù)并發(fā)運(yùn)行的,x86架構(gòu)CPU為了順應(yīng)時(shí)代潮流,在硬件層面上提供了專門的機(jī)制用來(lái)支持多任務(wù)的切換,這體現(xiàn)在兩個(gè)方面:

CPU內(nèi)部設(shè)置了一個(gè)專用的寄存器——任務(wù)寄存器TR,它指向當(dāng)前運(yùn)行的任務(wù)。

0f172cfe-a67f-11eb-aece-12bb97331649.png

定義了描述任務(wù)的數(shù)據(jù)結(jié)構(gòu)TSS,里面存儲(chǔ)了一個(gè)任務(wù)的上下文(一系列寄存器的值),下圖是一個(gè)32位CPU的TSS結(jié)構(gòu)圖:

0f4416b0-a67f-11eb-aece-12bb97331649.png

x86CPU的構(gòu)想是每一個(gè)任務(wù)對(duì)應(yīng)一個(gè)TSS,然后由TR寄存器指向當(dāng)前的任務(wù),執(zhí)行任務(wù)切換時(shí),修改TR寄存器的指向即可,這是硬件層面的多任務(wù)切換機(jī)制。

這個(gè)構(gòu)想其實(shí)還是很不錯(cuò)的,然而現(xiàn)實(shí)卻打了臉,包括Linux和Windows在內(nèi)的主流操作系統(tǒng)都沒(méi)有使用這個(gè)機(jī)制來(lái)進(jìn)行線程切換,而是自己使用軟件來(lái)實(shí)現(xiàn)多線程切換。

所以,絕大多數(shù)情況下,TR寄存器都是指向固定的,即便線程切換了,TR寄存器仍然不會(huì)變化。

注意,我這里說(shuō)的的是絕大多數(shù)情況,而沒(méi)有說(shuō)死。雖然操作系統(tǒng)不依靠TSS來(lái)實(shí)現(xiàn)多任務(wù)切換,但這并不意味著CPU提供的TSS操作系統(tǒng)一點(diǎn)也沒(méi)有使用。還是存在一些特殊情況,如一些異常處理會(huì)使用到TSS來(lái)執(zhí)行處理。

下面這張圖,展示了控制寄存器、描述符寄存器、任務(wù)寄存器構(gòu)成的全貌:

0f721e2a-a67f-11eb-aece-12bb97331649.png

模型特定寄存器

從80486之后的x86架構(gòu)CPU,內(nèi)部增加了一組新的寄存器,統(tǒng)稱為MSR寄存器,中文直譯是模型特定寄存器,意思是這些寄存器不像上面列出的寄存器是固定的,這些寄存器可能隨著不同的版本有所變化。這些寄存器主要用來(lái)支持一些新的功能。

隨著x86CPU不斷更新?lián)Q代,MSR寄存器變的越來(lái)越多,但與此同時(shí),有一部分MSR寄存器隨著版本迭代,慢慢固化下來(lái),成為了變化中那部分不變的,這部分MSR寄存器,Intel將其稱為Architected MSR,這部分MSR寄存器,在命名上,統(tǒng)一加上了IA32的前綴。

這里選取三個(gè)代表性的MSR簡(jiǎn)單介紹一下:

IA32_SYSENTER_CS

IA32_SYSENTER_ESP

IA32_SYSENTER_EIP

這三個(gè)MSR寄存器是用來(lái)實(shí)現(xiàn)快速系統(tǒng)調(diào)用。

在早期的x86架構(gòu)CPU上,系統(tǒng)調(diào)用依賴于軟中斷實(shí)現(xiàn),類似于前面調(diào)試用到的int 3指令,在Windows上,系統(tǒng)調(diào)用用到的是int 2e,在Linux上,用的是int 80。

軟中斷畢竟還是比較慢的,因?yàn)閳?zhí)行軟中斷就需要內(nèi)存查表,通過(guò)IDTR定位到IDT,再取出函數(shù)進(jìn)行執(zhí)行。

系統(tǒng)調(diào)用是一個(gè)頻繁觸發(fā)的動(dòng)作,如此這般勢(shì)必對(duì)性能有所影響。在進(jìn)入奔騰時(shí)代后,就加上了上面的三個(gè)MSR寄存器,分別存儲(chǔ)了執(zhí)行系統(tǒng)調(diào)用后,內(nèi)核系統(tǒng)調(diào)用入口函數(shù)所需要的段寄存器、堆棧棧頂、函數(shù)地址,不再需要內(nèi)存查表??焖傧到y(tǒng)調(diào)用還提供了專門的CPU指令sysenter/sysexit用來(lái)發(fā)起系統(tǒng)調(diào)用和退出系統(tǒng)調(diào)用。

在64位上,這一對(duì)指令升級(jí)為syscall/sysret。

總結(jié)以上就是全部要介紹的寄存器了,需要說(shuō)明一下的是,這并不是x86CPU全部所有的寄存器,除了這些,還存在XMM、MMX、FPU浮點(diǎn)數(shù)運(yùn)算等其他寄存器。

這篇文章以x86/x64架構(gòu)CPU為目標(biāo),通過(guò)對(duì)CPU內(nèi)部寄存器的闡述,串講了CPU執(zhí)行代碼機(jī)制、內(nèi)存尋址技術(shù)、中斷與異常處理、多任務(wù)管理、系統(tǒng)調(diào)用、調(diào)試原理等多種計(jì)算機(jī)底層知識(shí)。
編輯:lyn

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5300

    瀏覽量

    119860
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    10810

    瀏覽量

    210878

原文標(biāo)題:一口氣看完45個(gè)寄存器,CPU核心技術(shù)大揭秘

文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    接口的控制與狀態(tài)寄存器什么作用

    的行為并獲取硬件的狀態(tài)信息。 接口的控制與狀態(tài)寄存器作用 在現(xiàn)代計(jì)算機(jī)系統(tǒng)中,硬件設(shè)備與軟件之間的交互是通過(guò)一系列的接口來(lái)實(shí)現(xiàn)的。這些接口不僅需要能夠傳輸數(shù)據(jù),還需要能夠控制硬件設(shè)備的行為并監(jiān)控其狀態(tài)。接口的控制與狀態(tài)
    的頭像 發(fā)表于 10-17 10:42 ?239次閱讀

    微處理寄存器作用

    微處理中的寄存器是計(jì)算機(jī)體系結(jié)構(gòu)中的核心組成部分,它們扮演著至關(guān)重要的角色。寄存器是一種高速的存儲(chǔ)單元,用于暫時(shí)存儲(chǔ)數(shù)據(jù)、指令和地址等信息,以便微處理
    的頭像 發(fā)表于 10-05 15:07 ?251次閱讀

    ARM處理寄存器組織及功能

    ARM處理寄存器組織是其核心架構(gòu)的重要組成部分,對(duì)于理解ARM處理的運(yùn)行機(jī)制和性能特點(diǎn)具有重要意義。以下是對(duì)ARM處理
    的頭像 發(fā)表于 09-10 11:11 ?930次閱讀

    ARM寄存器的分類及功能

    ARM寄存器是ARM處理內(nèi)部的重要組成部分,它們?cè)谔幚?b class='flag-5'>器的運(yùn)算、控制以及數(shù)據(jù)存儲(chǔ)等方面發(fā)揮著至關(guān)重要的作用。下面,我們將從ARM寄存器的定
    的頭像 發(fā)表于 09-05 14:18 ?910次閱讀

    通用寄存器是什么意思

    在計(jì)算機(jī)體系結(jié)構(gòu)中,通用寄存器是中央處理CPU)內(nèi)部最為核心和基礎(chǔ)的組成部分之一。它們被設(shè)計(jì)為能夠存儲(chǔ)和傳輸各種類型的數(shù)據(jù)和指令,是CPU
    的頭像 發(fā)表于 09-05 14:13 ?575次閱讀

    寄存器的類型和作用

    在計(jì)算機(jī)科學(xué)中,寄存器(Register)是一種高速存儲(chǔ)單元,它位于CPU內(nèi)部,與CPU的運(yùn)算單元和邏輯控制單元緊密相連。寄存器的主要作用
    的頭像 發(fā)表于 09-05 14:11 ?895次閱讀

    寄存器尋址和直接尋址的區(qū)別

    寄存器尋址和直接尋址是計(jì)算機(jī)指令系統(tǒng)中的兩種基本尋址方式。它們?cè)谥噶畹膱?zhí)行過(guò)程中起著至關(guān)重要的作用,決定了指令操作數(shù)的來(lái)源和目標(biāo)。下面我們將介紹這兩種尋址方式的特點(diǎn)、區(qū)別以及在實(shí)際應(yīng)用中的優(yōu)缺點(diǎn)
    的頭像 發(fā)表于 07-12 10:42 ?1191次閱讀

    寄存器尋址的實(shí)現(xiàn)方式

    在計(jì)算機(jī)體系結(jié)構(gòu)中,寄存器尋址是一種常見(jiàn)的尋址方式,它允許程序直接訪問(wèn)CPU內(nèi)部的寄存器寄存器尋址可以提高程序的執(zhí)行效率,因?yàn)樗苊饬藢?duì)內(nèi)存的訪問(wèn)。
    的頭像 發(fā)表于 07-12 10:36 ?516次閱讀

    寄存器分為基本寄存器和什么兩種

    寄存器是計(jì)算機(jī)中用于存儲(chǔ)數(shù)據(jù)的高速存儲(chǔ)單元,它們是CPU內(nèi)部的重要組成部分。寄存器可以分為基本寄存器和擴(kuò)展寄存器兩種類型。 一、基本
    的頭像 發(fā)表于 07-12 10:31 ?1027次閱讀

    什么是寄存器?有哪些功能和應(yīng)用?

    有著至關(guān)重要的影響。本文將從寄存器的定義、分類、功能、與內(nèi)存的區(qū)別以及應(yīng)用等方面進(jìn)行詳細(xì)闡述,以便讀者能夠更全面地了解寄存器。
    的頭像 發(fā)表于 05-30 17:14 ?1.1w次閱讀

    CPU寄存器的用途

    在計(jì)算機(jī)體系結(jié)構(gòu)中,中央處理單元(CPU)無(wú)疑是整個(gè)系統(tǒng)的核心。CPU負(fù)責(zé)執(zhí)行指令、處理數(shù)據(jù)、控制計(jì)算機(jī)系統(tǒng)的運(yùn)行等關(guān)鍵任務(wù)。而在這個(gè)過(guò)程中,寄存器扮演著至關(guān)重要的角色。本文將詳細(xì)探討
    的頭像 發(fā)表于 05-30 17:09 ?1149次閱讀

    寄存器的定義和功能 寄存器的分類和工作原理

    在計(jì)算機(jī)系統(tǒng)中,寄存器作為一種特殊的存儲(chǔ)設(shè)備,扮演著至關(guān)重要的角色。它是中央處理CPU)內(nèi)部的重要組成部分,用于暫時(shí)存儲(chǔ)數(shù)據(jù)和指令,以便于CPU進(jìn)行高速的運(yùn)算和控制。本文將對(duì)
    的頭像 發(fā)表于 05-12 17:07 ?4912次閱讀

    干貨滿滿:ARM的內(nèi)核寄存器講解

    內(nèi)核寄存器與外設(shè)寄存器: 內(nèi)核寄存器與外設(shè)寄存器是完全不同的概念。內(nèi)核寄存器是指 CPU 內(nèi)部的
    發(fā)表于 04-17 11:47 ?2765次閱讀
    干貨滿滿:ARM的內(nèi)核<b class='flag-5'>寄存器</b>講解

    CPU的6個(gè)主要寄存器

    CPU寄存器是中央處理內(nèi)的組成部分,是有限存貯容量的高速存貯部件。寄存器CPU內(nèi)部的元件,包括通用
    的頭像 發(fā)表于 02-03 15:15 ?3745次閱讀

    arm三個(gè)寄存器在gdb調(diào)試時(shí)的作用

    arm三個(gè)寄存器在gdb調(diào)試時(shí)作用? ARM是一種廣泛使用的微處理架構(gòu),它廣泛應(yīng)用于移動(dòng)設(shè)備、嵌入式系統(tǒng)和其他高性能計(jì)算設(shè)備。當(dāng)我們?cè)谑褂胓db(GNU調(diào)試)調(diào)試ARM程序時(shí),
    的頭像 發(fā)表于 01-31 10:44 ?864次閱讀