最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

計(jì)算機(jī)程序基礎(chǔ)教程(02):x86處理器運(yùn)行方式

2023-02-06 06:04 作者:阿貍喜羊羊  | 我要投稿


1978年,英特爾發(fā)布了第一款使用x86指令集的處理器,命名為為8086,是一款16位處理器。

1982年,80286處理器上市,16位處理器,增加了保護(hù)模式。

1985年,80386處理器上市,32位處理器,增加了分頁(yè)管理內(nèi)存方式。

1989年,80486處理器上市,32位處理器,增加了浮點(diǎn)數(shù)運(yùn)算單元。

2003年,AMD對(duì)x86指令集進(jìn)行擴(kuò)充,稱為x86-64,用于64位處理器中,并發(fā)布了第一款64位x86處理器。


自此之后,對(duì)于程序制作者來(lái)說(shuō),x86系列處理器的基本運(yùn)行方式就沒(méi)有太大變化。




【指令的結(jié)構(gòu)】


控制器的運(yùn)行需要由指令控制,指令是一個(gè)二進(jìn)制數(shù)據(jù),計(jì)算機(jī)啟動(dòng)后,控制器會(huì)不斷的讀取存儲(chǔ)器中的指令,從而不間斷的運(yùn)行。


指令基本由如下幾個(gè)部分組成:


1.操作碼,確定處理器執(zhí)行什么功能,比如讀寫數(shù)據(jù)、數(shù)學(xué)運(yùn)算、邏輯運(yùn)算、等等。

2.地址碼,設(shè)置指令讀寫數(shù)據(jù)的位置,可以是寄存器、存儲(chǔ)單元地址,若要寫入的數(shù)據(jù)是固定的,也可以將數(shù)據(jù)直接存儲(chǔ)在地址碼中,這種數(shù)據(jù)稱為立即數(shù)。

3.操作數(shù)類型碼,確定操作數(shù)據(jù)的長(zhǎng)度,比如1字節(jié)、2字節(jié)、4字節(jié)等長(zhǎng)度。


一個(gè)數(shù)據(jù)既可以用來(lái)表示一個(gè)數(shù)值,也可以用來(lái)表示一個(gè)指令,為了區(qū)分兩者,文章之后的內(nèi)容將數(shù)據(jù)分為數(shù)值數(shù)據(jù)和指令數(shù)據(jù),避免混亂。




【指令的執(zhí)行方式】


指令有兩種基礎(chǔ)執(zhí)行方式:順序執(zhí)行、跳轉(zhuǎn)執(zhí)行。


處理器默認(rèn)以順序執(zhí)行的方式執(zhí)行指令,當(dāng)前指令執(zhí)行完畢后,讀取存儲(chǔ)器中之后的數(shù)據(jù)作為指令執(zhí)行。

而跳轉(zhuǎn)執(zhí)行可以讓指令不按照順序執(zhí)行,當(dāng)前指令執(zhí)行完畢后,可以按需求跳轉(zhuǎn)到之后或之前的某個(gè)地址處執(zhí)行。


?● 指令流水線與轉(zhuǎn)移預(yù)測(cè)


CPU為了提高指令的執(zhí)行速度,會(huì)將每一條指令的執(zhí)行分為多個(gè)步驟,然后使用流水線的方式執(zhí)行,當(dāng)前指令執(zhí)行時(shí),之后的指令已經(jīng)在流水線中進(jìn)行準(zhǔn)備工作。


若遇到需要跳轉(zhuǎn)執(zhí)行的指令,CPU會(huì)提前預(yù)測(cè)將要跳轉(zhuǎn)到的地址,然后讀取預(yù)測(cè)地址處的數(shù)據(jù)進(jìn)入流水線,這個(gè)預(yù)測(cè)的正確率一般為90%以上,但是無(wú)法做到100%,若判斷出錯(cuò),就要清空流水線中的任務(wù),重新來(lái)過(guò),為了避免這種情況的發(fā)生,高級(jí)編程語(yǔ)言的編譯器會(huì)盡量減少跳轉(zhuǎn)指令的使用,使用其他多條指令的組合也能實(shí)現(xiàn)跳轉(zhuǎn)指令的功能。


?● 指令調(diào)度策略


程序中指令的執(zhí)行是有順序的,但是有些指令不按順序執(zhí)行也不會(huì)出錯(cuò),此時(shí)CPU可能會(huì)改變某些指令的執(zhí)行順序、或者讓指令交叉執(zhí)行,當(dāng)指令需要等待數(shù)據(jù)傳入而進(jìn)入暫停狀態(tài)時(shí),直接執(zhí)行下一條指令。

編程語(yǔ)言的編譯器也會(huì)進(jìn)行相關(guān)優(yōu)化,對(duì)指令進(jìn)行重新排序,不會(huì)完全按照代碼的編寫順序進(jìn)行編譯,而是按照指令最優(yōu)的執(zhí)行順序去編譯。


?● 實(shí)模式與保護(hù)模式


最早的CPU其指令可以隨意跳轉(zhuǎn)執(zhí)行 、隨意訪問(wèn)任何內(nèi)存,隨著科學(xué)技術(shù)的進(jìn)步,人們需要在計(jì)算機(jī)中同時(shí)執(zhí)行多個(gè)程序,此時(shí)就需要一個(gè)稱為操作系統(tǒng)的程序來(lái)管理其他程序的運(yùn)行,并限制他們只能訪問(wèn)屬于自己的內(nèi)存區(qū)域,為此80286CPU有了保護(hù)模式,用于實(shí)現(xiàn)限制功能,之前對(duì)指令不進(jìn)行任何限制的模式稱為實(shí)模式。


保護(hù)模式將指令的權(quán)限分為4個(gè)等級(jí),使用0-3表示,0級(jí)權(quán)限最高,可以使用CPU的任何資源,高權(quán)限指令可以跳轉(zhuǎn)到低權(quán)限指令執(zhí)行,反之則不行,操作系統(tǒng)使用0級(jí)權(quán)限,從而控制其他程序的執(zhí)行,用戶程序使用3級(jí)權(quán)限,1-2級(jí)權(quán)限被操作系統(tǒng)廢棄不用。


CPU默認(rèn)以實(shí)模式運(yùn)行,修改控制寄存器CR0的PG位可以進(jìn)入保護(hù)模式,進(jìn)入保護(hù)模式后就不能再返回實(shí)模式。




【內(nèi)存管理方式】


最簡(jiǎn)單的CPU在指令讀寫一個(gè)內(nèi)存單元時(shí),直接通過(guò)一個(gè)數(shù)據(jù)指定內(nèi)存地址,此時(shí)程序必須放在固定的內(nèi)存地址處,放在其他位置就會(huì)執(zhí)行出錯(cuò),比如程序需要跳轉(zhuǎn)執(zhí)行時(shí),跳轉(zhuǎn)到的地址已經(jīng)寫死,無(wú)法改變。


?● 分段使用方式


8086處理器會(huì)將內(nèi)存分為很多段來(lái)使用,目的是方便程序重定位,指令通過(guò)兩個(gè)數(shù)據(jù)相加得到內(nèi)存地址,分別稱為段地址、偏移地址,段地址存儲(chǔ)內(nèi)存段的起始地址,偏移地址存儲(chǔ)內(nèi)存段的內(nèi)部編號(hào),偏移地址為0表示內(nèi)存段的第一個(gè)存儲(chǔ)單元、為1表示第二個(gè)存儲(chǔ)單元。


操作系統(tǒng)啟動(dòng)后,會(huì)首先將內(nèi)存分段,并在內(nèi)存中創(chuàng)建全局描述符表,用于記錄每個(gè)分段的起始地址、長(zhǎng)度、訪問(wèn)屬性等等信息。

程序執(zhí)行時(shí),只能占用操作系統(tǒng)設(shè)置好的分段,不能自己創(chuàng)建分段,操作系統(tǒng)會(huì)為每個(gè)執(zhí)行的程序創(chuàng)建一個(gè)局部描述符表,用于記錄此程序占用的內(nèi)存段相關(guān)信息。

指令讀寫內(nèi)存單元時(shí)只需要指定偏移地址即可,之后CPU通過(guò)查找描述符表將偏移地址與段地址相加,合成內(nèi)存地址,這樣就實(shí)現(xiàn)了將程序放在哪個(gè)位置都可以正確執(zhí)行。


?● 分頁(yè)使用方式


使用分段方式管理內(nèi)存時(shí),操作系統(tǒng)往往不會(huì)設(shè)置很小的分段,并且分段的數(shù)量是有上限的,使用不方便,容易造成浪費(fèi),為程序分配的內(nèi)存段大小不一定是程序需要使用的容量。

為了解決這個(gè)問(wèn)題,從80386開(kāi)始有了分頁(yè)管理內(nèi)存方式,處理器將內(nèi)存按照4KB的大小分成很多組,每一組稱為一個(gè)頁(yè),程序以頁(yè)為單位占用內(nèi)存,避免浪費(fèi)。


啟用分頁(yè)機(jī)制后,指令依然使用分段的方式讀寫內(nèi)存,目的是為了保留分段的優(yōu)勢(shì),讓程序放在內(nèi)存中的任何位置都能正確執(zhí)行。

但是此時(shí)段地址+偏移地址合成的地址已經(jīng)不是真實(shí)的內(nèi)存地址,為了避免混亂,此時(shí)段地址+偏移地址合成的地址稱為虛擬地址。


計(jì)算機(jī)文件有一個(gè)文件偏移地址的概念,它的作用是為文件內(nèi)數(shù)據(jù)按存儲(chǔ)順序分配編號(hào),第一個(gè)字節(jié)分配編號(hào)0、第二個(gè)字節(jié)編號(hào)為1、直到最后一個(gè)字節(jié),通過(guò)這個(gè)編號(hào)調(diào)用文件內(nèi)數(shù)據(jù)比較方便,無(wú)需知道文件存放在哪個(gè)位置。就好比使用火車托運(yùn)貨物,你只需要記錄火車車廂的編號(hào)即可,無(wú)論火車走到哪里,你只要告訴管理人員你的貨物在幾號(hào)車廂,就能拿走你的貨物,至于火車停在哪個(gè)軌道上,你無(wú)需關(guān)心,那是管理人員的事。


虛擬地址的作用就類似文件偏移地址,它用來(lái)為程序內(nèi)部的數(shù)據(jù)分配編號(hào),虛擬地址雖然也叫地址,但是它與內(nèi)存地址已經(jīng)沒(méi)有一毛關(guān)系。

操作系統(tǒng)啟動(dòng)后,首先啟用保護(hù)模式,然后啟用分頁(yè)機(jī)制,程序執(zhí)行時(shí)操作系統(tǒng)為其按頁(yè)分配內(nèi)存,并創(chuàng)建一個(gè)頁(yè)表,用于記錄程序占用了哪些頁(yè)、每個(gè)頁(yè)的屬性等信息,此時(shí)虛擬地址會(huì)與內(nèi)存物理地址建立映射關(guān)系,指令通過(guò)虛擬地址說(shuō)明要調(diào)用程序內(nèi)的第幾個(gè)數(shù)據(jù),至于這個(gè)數(shù)據(jù)編號(hào)對(duì)應(yīng)哪個(gè)內(nèi)存地址,指令不關(guān)心,也無(wú)需知道,CPU會(huì)根據(jù)頁(yè)表中的記錄將虛擬地址轉(zhuǎn)換為內(nèi)存物理地址,之后執(zhí)行指令。




【寄存器】


寄存器按功能的不同基本可以分為5類:通用寄存器、段地址寄存器、偏移地址寄存器、標(biāo)志寄存器、控制寄存器。


?● 通用寄存器


通用寄存器可以存儲(chǔ)任何數(shù)據(jù),又分為多種長(zhǎng)度類型,64位寄存器只存在于64位CPU中,但是同時(shí)也包含32位、16位、8位寄存器。


x86-64處理器中的通用寄存器如下:


64位:rax、rbx、rcx、rdx,最早的x86指令集定義的通用寄存器,在x86-64中長(zhǎng)度擴(kuò)展為64。

64位:r8、r9、r10、r11、r12、r13、r14、r15,x86-64指令集新增的寄存器。


32位:eax、ebx、ecx、edx,由64位的rax-rdx拆分形成,不能與對(duì)應(yīng)的64位寄存器同時(shí)使用,使用rax時(shí)不能同時(shí)使用eax,下同。

32位:r8d、r9d、r10d、r11d、r12d、r13d、r14d、r15d,由64位的r8-r15拆分形成,只存在于x86-64指令集中,x86指令集沒(méi)有,下同。


16位:ax、bx、cx、dx,由32位的eax-edx拆分形成。

16位:r8w、r9w、r10w、r11w、r12w、r13w、r14w、r15w,由64位的r8-r15拆分形成,只存在于x86-64指令集中。


8位:al、bl、cl、dl、ah、bh、ch、dh,由16位的ax-dx拆分形成,ax的低8位為al,高8位為ah。

8位:r8b、r9b、r10b、r11b、r12b、r13b、r14b、r15b,由64位的r8-r15拆分形成,只存在于x86-64指令集中。


?● 段地址寄存器


8086處理器定義了4個(gè)段地址寄存器:CS、DS、ES、SS。


CS存放指令數(shù)據(jù)的段地址。

DS存放數(shù)值數(shù)據(jù)的段地址。

SS存放棧空間的段地址。

ES是輔助段寄存器,供程序自由安排使用。


80386處理器新增了兩個(gè)輔助段寄存器:FS、GS。


啟用保護(hù)模式后,CS寄存器中存放的不再是段地址,而是段選擇子,用來(lái)存儲(chǔ)操作系統(tǒng)設(shè)置好的內(nèi)存段編號(hào)、并記錄指令的特權(quán)級(jí)別。


?● 偏移地址寄存器


8086處理器定義了5個(gè)偏移地址寄存器:IP、SP、BP、SI、DI。


IP,存放指令數(shù)據(jù)的偏移地址,CS+IP合成的內(nèi)存地址處理器就認(rèn)為是指令,會(huì)從這里開(kāi)始順序執(zhí)行。

SP,存儲(chǔ)??臻g的偏移地址,push、pop棧操作指令會(huì)影響SP的值。

BP,存儲(chǔ)??臻g的偏移地址,push、pop棧操作指令不會(huì)影響B(tài)P的值,使用mov指令讀寫棧空間時(shí)一般使用BP寄存器存儲(chǔ)偏移地址,此時(shí)處理器默認(rèn)SS為段寄存器。

SI、DI,存儲(chǔ)數(shù)值數(shù)據(jù)的偏移地址,服務(wù)于讀寫數(shù)組相關(guān)指令,比如movsb、movsw。


32位處理器中,偏移地址寄存器的長(zhǎng)度擴(kuò)充為32位,使用32位模式時(shí),名稱前添加E字母,比如:EIP、EDI。

64位處理器中,偏移地址寄存器的長(zhǎng)度擴(kuò)充為64位,使用64位模式時(shí),名稱前添加R字母,比如:RIP、RDI。


SP、BP、SI、DI也可以當(dāng)做通用寄存器使用,在x86-64指令集中,SP、BP、SI、DI又可以拆分形成4個(gè)8位寄存器:SPL、BPL、SIL、DIL,這4個(gè)8位寄存器只存在于x86-64指令集中。


?● 標(biāo)志寄存器


8086處理器有一個(gè)標(biāo)志寄存器,名為FLAGS,長(zhǎng)度16位,用于記錄指令執(zhí)行結(jié)果、或者設(shè)置處理器的某些功能,每一種信息使用一個(gè)二進(jìn)制位記錄,常用位如下:


CF位:

進(jìn)位標(biāo)志位,記錄無(wú)符號(hào)數(shù)加法運(yùn)算結(jié)果是否發(fā)生溢出,或者減法運(yùn)算轉(zhuǎn)加法后是否發(fā)生溢出。

當(dāng)進(jìn)行無(wú)符號(hào)數(shù)加法時(shí),記錄加法結(jié)果是否因長(zhǎng)度過(guò)大導(dǎo)致溢出,若溢出則CF位存儲(chǔ)1,否則CF為0。

當(dāng)進(jìn)行無(wú)符號(hào)數(shù)減法時(shí),減法會(huì)轉(zhuǎn)換為加法,若加補(bǔ)碼運(yùn)算沒(méi)有溢出,則CF位存儲(chǔ)1,否則存儲(chǔ)0,此時(shí)可以理解為運(yùn)算結(jié)果為負(fù)數(shù),使用補(bǔ)碼存儲(chǔ),但是這里服務(wù)于無(wú)符號(hào)數(shù),所以此時(shí)用于記錄被減數(shù)小于減數(shù)這種關(guān)系,同時(shí)也可以理解為被減數(shù)向一個(gè)不存在的高位借位,從而得出一個(gè)正數(shù)結(jié)果,某些減法指令會(huì)使用CF位的值。


OF位:

溢出標(biāo)志位,記錄有符號(hào)數(shù)加法結(jié)果是否發(fā)生溢出,若溢出則OF位存儲(chǔ)1,否則為0。


SF位:

符號(hào)標(biāo)志位,記錄有符號(hào)數(shù)減法運(yùn)算結(jié)果是否為負(fù),若為負(fù)則SF位存儲(chǔ)1,若為正存儲(chǔ)0。


ZF位:

0標(biāo)志位,記錄數(shù)學(xué)運(yùn)算、邏輯運(yùn)算、數(shù)據(jù)比較等指令的執(zhí)行結(jié)果中是否所有位都為0,若為0則ZF存儲(chǔ)1,否則存儲(chǔ)0。

可用于判斷一個(gè)未知數(shù)是否與一個(gè)已知數(shù)相等,將兩者進(jìn)行減法運(yùn)算即可。

無(wú)符號(hào)數(shù)與有符號(hào)數(shù)都可以通過(guò)此位來(lái)判斷減法結(jié)果是否為0,當(dāng)有符號(hào)數(shù)減法結(jié)果為0時(shí),符號(hào)位也為0,這里體現(xiàn)出了有符號(hào)數(shù)只有+0沒(méi)有-0的優(yōu)勢(shì)。


PF位:

奇偶標(biāo)志位,記錄運(yùn)算指令結(jié)果的低8位中數(shù)字1的個(gè)數(shù)是否為偶數(shù),若為偶數(shù)則存儲(chǔ)1,若為奇數(shù)則存儲(chǔ)0。


DF位:

方向標(biāo)志位,設(shè)置movsb等數(shù)組指令讀寫數(shù)據(jù)的方向。

若DF位為0,執(zhí)行movsb指令時(shí)si、di寄存器各自加1,執(zhí)行movsw指令時(shí)si、di寄存器各自加2。

若DF位為1,執(zhí)行movsb指令時(shí)si、di寄存器各自減1,執(zhí)行movsw指令時(shí)si、di寄存器各自減2。


TF位:

設(shè)置是否產(chǎn)生單步中斷,用于調(diào)試程序。


IF位:

設(shè)置處理器是否接收可被屏蔽的外中斷,若為1則接收,為0不接收。


?● 控制寄存器


用來(lái)設(shè)置處理器工作模式的轉(zhuǎn)換、緩存的禁用與啟用、虛擬地址的轉(zhuǎn)換等等功能。

80386有4個(gè)控制寄存器:CR0 - CR3,其中CR1保留不用,而x86-64指令集定義了CR0-CR15共16個(gè)控制寄存器,但只使用其中的CRO、CR2、CR3、CR4、CR8。


CR0的PE位用來(lái)設(shè)置是否啟用保護(hù)模式,若為1則啟用保護(hù)模式,進(jìn)入保護(hù)模式后不能再回到實(shí)模式,PG位用來(lái)設(shè)置是否啟用內(nèi)存分頁(yè)管理模式,啟用分頁(yè)模式之前必須首先啟用保護(hù)模式。




【中斷】


CPU執(zhí)行一個(gè)程序時(shí),若發(fā)生了一些重要事件,需要暫停程序,轉(zhuǎn)而去處理事件,這時(shí)候就需要使用中斷功能。

每一種中斷都會(huì)有一個(gè)編號(hào),可以為每一種中斷綁定一個(gè)處理程序,當(dāng)發(fā)生中斷后,CPU會(huì)去執(zhí)行中斷處理程序,執(zhí)行完畢后再返回之前的程序執(zhí)行。


CPU外部產(chǎn)生的中斷稱為外中斷,CPU對(duì)外連接的某些引腳用于外中斷功能,通過(guò)改變它的電壓來(lái)告知CPU是否有事件發(fā)生,比如按下鍵盤按鍵后會(huì)向CPU發(fā)出一個(gè)外中斷,告知CPU輸入設(shè)備有數(shù)據(jù)發(fā)送。外中斷分為可屏蔽中斷與不可屏蔽中斷,大多數(shù)外中斷都是可屏蔽的,可通過(guò)修改標(biāo)志寄存器中的IF位屏蔽這些外中斷。


CPU內(nèi)部產(chǎn)生的中斷稱為內(nèi)中斷或者異常,比如除數(shù)為0時(shí)會(huì)產(chǎn)生一個(gè)內(nèi)中斷,也可以通過(guò)執(zhí)行int指令人為產(chǎn)生一個(gè)內(nèi)中斷,用戶程序使用系統(tǒng)調(diào)用時(shí)就是通過(guò)這種方式實(shí)現(xiàn),因?yàn)橛脩舫绦驘o(wú)法跳轉(zhuǎn)到操作系統(tǒng)內(nèi)核執(zhí)行,所以用戶程序會(huì)通過(guò)int指令發(fā)出一個(gè)內(nèi)中斷,并設(shè)置一些參數(shù),操作系統(tǒng)接收到內(nèi)中斷后根據(jù)參數(shù)執(zhí)行系統(tǒng)調(diào)用。



計(jì)算機(jī)程序基礎(chǔ)教程(02):x86處理器運(yùn)行方式的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
武乡县| 新野县| 天津市| 定边县| 宜宾市| 安阳市| 靖宇县| 浠水县| 茂名市| 邵武市| 临泽县| 桃园市| 大庆市| 博兴县| 敖汉旗| 葫芦岛市| 定安县| 三原县| 丹凤县| 盐边县| 大厂| 四会市| 东辽县| 南安市| 南投县| 南靖县| 峡江县| 山东| 南平市| 桃园县| 乃东县| 枣阳市| 吉林省| 巨野县| 涿鹿县| 上犹县| 泾阳县| 阳信县| 阿鲁科尔沁旗| 东乡族自治县| 名山县|