日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

《操作系统真象还原》——0.25 指令集、体系结构、微架构、编程语言

發(fā)布時(shí)間:2024/3/13 windows 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《操作系统真象还原》——0.25 指令集、体系结构、微架构、编程语言 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本節(jié)書(shū)摘來(lái)自異步社區(qū)《操作系統(tǒng)真象還原》一書(shū)中的第0章,第0.25節(jié),作者:鄭鋼著,更多章節(jié)內(nèi)容可以訪問(wèn)云棲社區(qū)“異步社區(qū)”公眾號(hào)查看

0.25 指令集、體系結(jié)構(gòu)、微架構(gòu)、編程語(yǔ)言

指令集是什么?表面上看它是一套指令的集合。集合的意思顯而易見(jiàn),那咱們說(shuō)說(shuō)什么是指令。

在計(jì)算機(jī)中,CPU只能識(shí)別0、1這兩個(gè)數(shù),甚至它都不知道數(shù)是什么,它只知道要么“是”,要么“不是”,恰好用0、1來(lái)表示這兩種狀態(tài)而已。

人發(fā)明的東西逃不出人的思維,所以,先看看我們?nèi)祟?lèi)的語(yǔ)言是怎么回事。

不同的語(yǔ)言對(duì)同一種事物有不同的名字,這個(gè)名字其實(shí)就是代碼。比如說(shuō)人類(lèi)的好朋友:狗,咱們?cè)谥形睦锓Q(chēng)之為狗,但在英文中它被稱(chēng)為dog,雖然用了兩種語(yǔ)言,但其描述的都是這種會(huì)汪汪叫、對(duì)人類(lèi)無(wú)比忠誠(chéng)的動(dòng)物。人是怎樣識(shí)別小狗的呢?識(shí)別信息來(lái)自聽(tīng)覺(jué)、視覺(jué)等,這是因?yàn)槿颂焐邆涮幚砺曇艉蛨D像的能力,能夠識(shí)別出各種不同的聲音和顏色不同的圖像。可是計(jì)算機(jī)只能處理0、1這兩個(gè)數(shù),所以讓計(jì)算機(jī)識(shí)別某個(gè)事物,只有用01這兩個(gè)數(shù)來(lái)定義。也就是說(shuō),要用0、1來(lái)為各種事物編碼。

為了更好地說(shuō)明指令集,咱們這里不再用現(xiàn)有的語(yǔ)言舉例子,當(dāng)然也不是要自創(chuàng)指令集。下面舉個(gè)簡(jiǎn)單的例子來(lái)演示指令集的模型。

咱們拿表達(dá)式A=B+C為例。假設(shè)A、B、C都是內(nèi)存變量的值,它們的地址分別是0x3000、0x3004、0x3008。在此用Ra表示寄存器A,Rb表示寄存器B,Rc表示寄存器C。

完成這個(gè)加法的步驟是先將B和C載入到Ra和Rb寄存器中,再將兩個(gè)寄存器的值相加后送入寄存器Ra,之后再將寄存器Ra的值寫(xiě)入到地址為0x3000的內(nèi)存中。

步驟有了,咱們?cè)僭O(shè)計(jì)完成這些步驟的指令。

步驟1:將內(nèi)存中的數(shù)據(jù)載入到寄存器,咱們假設(shè)它的指令名為load。

步驟2:兩個(gè)寄存器的加法指令,假設(shè)指令名為add。

步驟3:將寄存器中的內(nèi)容存儲(chǔ)到內(nèi)存,假設(shè)指令名為store。

以上指令名都是假設(shè)的,名字可以任意取,因?yàn)镃PU不識(shí)別指令名。指令名是編譯器用來(lái)給人看的,為的是方便人來(lái)編程,CPU它只認(rèn)編碼。目前CPU中的指令,無(wú)論是哪種指令集,都由操作碼和操作數(shù)兩部分組成(有些指令即使指令格式中沒(méi)有列出操作數(shù),也會(huì)有隱含的操作數(shù))。咱們也采用這種操作碼+操作數(shù)的思路,分別為這兩部分編碼。

咱們先為操作碼設(shè)計(jì)編碼。

接下來(lái)為操作數(shù)編碼,操作數(shù)一般是立即數(shù)、寄存器、內(nèi)存等,咱們這里主要是為寄存器編碼。

好啦,操作碼和操作數(shù)都有了,其實(shí)指令集已經(jīng)完成了。不過(guò)在一長(zhǎng)串的二進(jìn)制01中,哪些是操作碼,哪些是操作數(shù)呢?這就是指令格式的由來(lái)啦。我們?nèi)藶橐?guī)定個(gè)格式,規(guī)定操作碼和操作數(shù)的大小及位置,然后在CPU硬件電路中寫(xiě)死這些規(guī)則,讓CPU在硬件一級(jí)上識(shí)別這些格式,從而能識(shí)別出操作碼和操作數(shù)。

假設(shè)我們的指令格式最大支持三個(gè)寄存器參數(shù)和一個(gè)立即數(shù)參數(shù)。其中操作碼和各寄存器操作數(shù)各占1字節(jié),立即數(shù)部分占4字節(jié)。各條指令并不是完全按照此格式填充,不同的指令有不同的參數(shù),只有操作碼部分是固定的,其他操作數(shù)部分是可選的。當(dāng)CPU在譯碼階段識(shí)別出操作碼后,CPU自然知道該指令需要什么樣的操作數(shù),這是寫(xiě)死在硬件電路中的,所以不同的指令其機(jī)器碼長(zhǎng)度很可能不一致。

為了演示指令集模型,我們?cè)谏厦婕僭O(shè)了寄存器名、指令名、格式。按理說(shuō)這對(duì)于指令集來(lái)說(shuō)已經(jīng)全了,不過(guò),為方便咱們了解編譯器,不如咱們?cè)偌僭O(shè)個(gè)指令的語(yǔ)法吧,咱們這里學(xué)習(xí)Intel的語(yǔ)法格式:“指令目的操作數(shù),源操作數(shù)”。目的操作數(shù)在左,源操作數(shù)在右,此賦值順序比較直觀。Intel想表達(dá)的是 a=b這種語(yǔ)序,如a=b,便是mov a,b。

以上三個(gè)步驟的機(jī)器碼按照十六進(jìn)制表示為:

以上自定義的指令便是按照咱們假設(shè)的語(yǔ)法來(lái)生成的。對(duì)于機(jī)器碼的大小,由于指令不同,需要的操作數(shù)也不同,所以機(jī)器碼大小也不同。另外,機(jī)器碼中的立即數(shù)是按照x86架構(gòu)的小端字節(jié)序?qū)懙?#xff0c;這一點(diǎn)大家要注意。小端字節(jié)序是數(shù)值中的低位在低地址,高位在高地址,數(shù)位以字節(jié)為單位。前面有一小節(jié)說(shuō)明大小端字節(jié)序問(wèn)題。

步驟2的機(jī)器碼為01 00 01 10。操作碼占1字節(jié),CPU識(shí)別出第1字節(jié)的二進(jìn)制01是add指令,知道此指令的操作數(shù)是3個(gè)寄存器,并且第1個(gè)寄存器操作數(shù)是目的寄存器,另外兩個(gè)寄存器是源操作數(shù)(這都是我們假定的,并且是寫(xiě)死在硬件中的規(guī)則,不同的指令有不同的規(guī)則,您也可以創(chuàng)造出內(nèi)存和寄存器混合作為操作數(shù)的加法指令)。于是到第2字節(jié)去讀取寄存器編碼,發(fā)現(xiàn)其值為二進(jìn)制00,就是寄存器Ra對(duì)應(yīng)的編碼。接著到下一個(gè)字節(jié)處繼續(xù)讀出寄存器編碼,發(fā)現(xiàn)是二進(jìn)制01,也就是寄存器Rb,Rc同理。于是將寄存器Rb和Rc的值相加后存入到寄存器Ra。

步驟3中,機(jī)器碼為10 00 0c300000,CPU讀取機(jī)器碼的第1 字節(jié)發(fā)現(xiàn)其為二進(jìn)制10,知道其為指令store,于是便確定了,目的操作數(shù)是個(gè)立即數(shù)形式的內(nèi)存地址,源操作數(shù)是個(gè)寄存器。接著到指令格式中的寄存器操作數(shù)1的位置去讀取寄存器編碼,發(fā)現(xiàn)其值為00,這就是寄存器Ra的編碼。機(jī)器碼中剩下的部分便作為立即數(shù),這樣便將寄存器Ra的值寫(xiě)入到內(nèi)存0x0000300c中了。

以上指令集的模型,確實(shí)太過(guò)于簡(jiǎn)單了,也許稱(chēng)之為模型都非常勉強(qiáng)。現(xiàn)實(shí)中的指令格式要遠(yuǎn)遠(yuǎn)復(fù)雜得多。下面我們看看目前世面上的指令集有哪些。

最早的指令集是CISC(Complex Instruction Set Computer),意為復(fù)雜指令集計(jì)算機(jī)。從名字上看,這套指令集相當(dāng)復(fù)雜,當(dāng)初這套指令集問(wèn)世的時(shí)候,它的研發(fā)者們都沒(méi)想過(guò)要給它起名,只是因?yàn)楹髞?lái)出現(xiàn)了相對(duì)精簡(jiǎn)高效的指令集,所以人們?yōu)榱思右詤^(qū)分,才將最初的這套相對(duì)復(fù)雜的指令集命名為CISC,而后來(lái)精簡(jiǎn)高效的指令集稱(chēng)為RISC(Reduced Instruction Set Computer)。

CISC和RISC并不是具體的指令集,而是兩種不同的指令體系,相當(dāng)于指令集中的門(mén)派,是指令的設(shè)計(jì)思想。舉個(gè)例子,就像中醫(yī)與西醫(yī),中醫(yī)講究從整體上調(diào)理身體,西醫(yī)則更多的是偏向局部。這就是兩種不同的醫(yī)療思路,類(lèi)似于CISC和RISC這兩種指令體系。那什么是指令集呢?拿中醫(yī)舉例,像華佗、張仲景這兩位醫(yī)圣,他們雖然都是基于中醫(yī)的思想治病,但醫(yī)術(shù)各有特色,水平也不盡相同,這就相當(dāng)于不同的指令集。一會(huì)兒咱們會(huì)介紹具體的指令集。

為什么說(shuō)CISC復(fù)雜呢?

首先,因?yàn)樗亲钤绲闹噶罴?#xff0c;當(dāng)初都是摸著石頭過(guò)河,肯定有一些瑕疵在里面。其次,當(dāng)初的程序員都是用匯編語(yǔ)言開(kāi)發(fā)程序,他們當(dāng)然希望匯編語(yǔ)言強(qiáng)大啦,盡量多一些指令,盡量一個(gè)指令能多干幾件事,所以指令集中的指令越來(lái)越多,越來(lái)越復(fù)雜。不過(guò)這樣的好處是程序員同學(xué)很爽。最后,CISC是Intel使用的指令集,Intel公司在兼容性方面做得最好,指令集在發(fā)展的過(guò)程中,還要兼容過(guò)去有瑕疵的古董,以至于最后的指令集變得有點(diǎn)“奇形怪狀”了。

作為后起之秀的RISC,借鑒了前輩CISC的經(jīng)驗(yàn),取其精華,棄其糟粕,當(dāng)然要更好更輕量啦。它是怎么來(lái)的呢?

CISC不是做得很全很強(qiáng)嗎,可是很多時(shí)候,程序員并不會(huì)用到那些復(fù)雜的指令和尋址方式,即使用到了,編譯器有時(shí)候?yàn)榱藘?yōu)化,未必“全”將其編譯為復(fù)雜的形式。這就導(dǎo)致了CPU中的復(fù)雜的指令和尋址方式無(wú)用武之地。根據(jù)二八定律,指令集中20%的簡(jiǎn)單指令占了程序的80%,而指令集中80%的復(fù)雜指令占了程序的20%。根據(jù)這個(gè)特性,處理器及指令集被重新設(shè)計(jì),保留了那些基本常用的指令,減少了硬件電路的復(fù)雜性。這樣,大部分指令都能在一個(gè)時(shí)鐘周期內(nèi)完成,更有利于提升流水線的效率。而且,指令采用了定長(zhǎng)編碼,這樣譯碼工作更容易了。由于其太優(yōu)秀了,后來(lái)的處理器,如MIPS,ARM,Power都采用RISC指令體系,做得最好的就是MIPS處理器,它嚴(yán)格遵守RISC思想,業(yè)界公認(rèn)其優(yōu)雅。

我們常用的CPU是Intel和AMD公司的產(chǎn)品,它們用的指令集便是基于CISC思想的x86。AMD的x86指令架構(gòu)是Intel授權(quán)給他們的,為區(qū)別于此,Intel在官方手冊(cè)上稱(chēng)自己的指令集為IA32。

雖然AMD采用的也是x86指令集,但I(xiàn)ntel可沒(méi)把硬件實(shí)現(xiàn)方法也告訴AMD,否則AMD的CPU和Intel的CPU不就完全一樣了嗎,人家Intel也不肯呢。指令集是一套約定,里面規(guī)定的是有哪些指令、指令的二進(jìn)制編碼、指令格式等,如何實(shí)現(xiàn)這套約定,這是硬件自己的事。打個(gè)比方,這就像和朋友約好了在某餐廳吃飯,咱是坐車(chē)去,還是走著去,這是咱們的事,與吃飯是無(wú)關(guān)的。說(shuō)白了,在Intel的CPU上運(yùn)行的軟件也能夠在AMD的CPU上運(yùn)行,原因就是它們共用了同用一套指令集,也就是對(duì)二進(jìn)制編碼達(dá)成了共識(shí)。它們面對(duì)相同的需求,可能采取了不同的行動(dòng),但都完成了任務(wù)。比如機(jī)器碼是b80000,Intel的CPU經(jīng)過(guò)譯碼,知道這是將0賦值給寄存器ax,相當(dāng)于匯編語(yǔ)言mov ax,0。AMD的CPU在譯碼時(shí),也得將此機(jī)器碼認(rèn)為是將0賦值給寄存器ax。至于它們?cè)谖锢砩鲜窃趺磳?傳入寄存器ax中的,這是它們各自實(shí)現(xiàn)的方式,與指令集無(wú)關(guān)。它們各自實(shí)現(xiàn)的方式,就叫微架構(gòu)。

總結(jié)一下,指令集是具體的一套指令編碼,微架構(gòu)是指令集的物理實(shí)現(xiàn)方式。

發(fā)展到后來(lái),x86指令集越來(lái)越復(fù)雜。它本屬于CISC體系,但由于效率低下,最終在其內(nèi)部實(shí)現(xiàn)上采取了RISC內(nèi)核,即一條CISC指令在譯碼時(shí),分解成多條RISC指令,這樣其執(zhí)行效率便可與RISC媲美啦。

目前市面上常見(jiàn)的指令集有五種,除x86是CISC指令體系外,ARM、MIPS、Power、C6000都是RISC指令體系的指令集。

CPU與指令集是對(duì)應(yīng)的,一種CPU只能識(shí)別一種指令集,所以很多CPU都以其支持的指令集來(lái)稱(chēng)呼。比如ARM、MIPS,它們本身是CPU名稱(chēng),又是指令集名稱(chēng)。

ARM主要用在手機(jī)中,作為手機(jī)的處理器。Power是IBM用于服務(wù)器上的處理器。C6000是數(shù)字信號(hào)處理器,廣泛用于視頻處理。而MIPS雖然本身很優(yōu)秀,但其在各領(lǐng)域起步都較晚,并沒(méi)有廣泛應(yīng)用的領(lǐng)域。

由于MIPS本身的優(yōu)越性,龍芯用的就是mips指令集,有沒(méi)有人問(wèn),為什么咱們自主研發(fā)的CPU還要用人家國(guó)外的指令集?就不能也研發(fā)出一套指令集嗎?能倒是能,不過(guò)語(yǔ)言不通用。就像我自己可以發(fā)明一門(mén)語(yǔ)言,語(yǔ)言本身沒(méi)什么問(wèn)題,問(wèn)題是我用自己發(fā)明的語(yǔ)言和別人交流,誰(shuí)聽(tīng)得懂呢,誰(shuí)又愿意去學(xué)這門(mén)語(yǔ)言呢?大家都很忙,不通用的東西沒(méi)人愿意花精力去學(xué)。如果龍芯也自立門(mén)戶(hù)創(chuàng)造新的指令集,那有誰(shuí)愿意給它寫(xiě)編譯器呢?即使有了編譯器,操作系統(tǒng)也要重新編譯發(fā)布,應(yīng)用程序也要重新編譯發(fā)布,指令集背后不僅是個(gè)計(jì)算機(jī)生態(tài)鏈,更重要的是全球經(jīng)濟(jì)鏈。

平時(shí)所說(shuō)的編程語(yǔ)言,雖然其上層表現(xiàn)各異,歸根結(jié)底是要在具體的CPU上運(yùn)行的,所以必須由編譯器按照該CPU的指令集,翻譯成符合該CPU的指令。說(shuō)到這,不得不說(shuō)一下交叉編譯,本質(zhì)上交叉編譯就是用在A平臺(tái)上運(yùn)行的編譯器,編譯出符合B平臺(tái)CPU指令集的程序,編譯出的程序直接能在B平臺(tái)上運(yùn)行啦。這里的平臺(tái)指的就是CPU指令體系結(jié)構(gòu)。

總結(jié)

以上是生活随笔為你收集整理的《操作系统真象还原》——0.25 指令集、体系结构、微架构、编程语言的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。