指令集侣灶、體系架構(gòu)、微架構(gòu) [轉(zhuǎn)]

指令集缕碎、體系架構(gòu)褥影、微架構(gòu) [轉(zhuǎn)]

轉(zhuǎn)載自《操作系統(tǒng)真相還原》

指令集是什么?表面上看它是一套指令的集合阎曹。集合的意思顯而易見伪阶,那咱們說說什么是指令。

在計算機中处嫌,CPU只能識別0激率、1這兩個數(shù)够话,甚至它都不知道數(shù)是什么,它只知道要么“是”,要么“不是”迅办,恰好用0、1來表示這兩種狀態(tài)而已季眷。

人發(fā)明的東西逃不出人的思維猫牡,所以,先看看我們?nèi)祟惖恼Z言是怎么回事捆昏。

不同的語言對同一種事物有不同的名字赚楚,這個名字其實就是代碼。比如說人類的好朋友:狗骗卜,咱們在中文里稱之為狗宠页,但在英文中它被稱為dog,雖然用了兩種語言寇仓,但其描述的都是這種會汪汪叫举户、對人類無比忠誠的動物。人是怎樣識別小狗的呢遍烦?識別信息來自聽覺俭嘁、視覺等,這是因為人天生具備處理聲音和圖像的能力服猪,能夠識別出各種不同的聲音和顏色不同的圖像供填。可是計算機只能處理0蔓姚、1這兩個數(shù)捕虽,所以讓計算機識別某個事物,只有用01這兩個數(shù)來定義坡脐。也就是說泄私,要用0、1來為各種事物編碼备闲。

為了更好地說明指令集晌端,咱們這里不再用現(xiàn)有的語言舉例子,當然也不是要自創(chuàng)指令集恬砂。下面舉個簡單的例子來演示指令集的模型咧纠。

咱們拿表達式A=B+C 為例。假設(shè)A 泻骤、B 漆羔、C 都是內(nèi)存變量的值梧奢,它們的地址分別是Ox3000 、Ox3004 演痒、Ox3008 亲轨。在此用Ra 表示寄存器A, Rb 表示寄存器B, Re 表示寄存器c.

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

步驟有了,咱們再設(shè)計完成這些步驟的指令讯嫂。

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

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

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

以上指令名都是假設(shè)的巫湘,名字可以任意取,因為CPU 不識別指令名昏鹃。指令名是編譯器用來給人看的尚氛,為的是方便人來編程, CPU 它只認編碼洞渤。目前CPU 中的指令阅嘶,無論是哪種指令集,都由操作碼和操作數(shù)兩部分組成(有些指令即使指令格式中沒有列出操作數(shù)载迄,也會有隱含的操作數(shù))讯柔。咱們也采用這種操作碼+操作數(shù)的思路,分別為這兩部分編碼护昧。

咱們先為操作碼設(shè)計編碼魂迄。

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

好啦湿酸,操作碼和操作數(shù)都有了,其實指令集己經(jīng)完成了灭美。不過在一長串的二進制01 中推溃,哪些是操作碼,哪些是操作數(shù)呢届腐?這就是指令格式的由來啦铁坎。我們?nèi)藶橐?guī)定個格式蜂奸,規(guī)定操作碼和操作數(shù)的大小及位置,然后在CPU 硬件電路中寫死這些規(guī)則硬萍,讓CPU 在硬件一級上識別這些格式窝撵,從而能識別出操作碼和操作數(shù)。

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

為了演示指令集模型盖呼,我們在上面假設(shè)了寄存器名儒鹿、指令名、格式几晤。按理說這對于指令集來說已經(jīng)全了约炎,不過,為方便咱們了解編譯器蟹瘾,不如咱們再假設(shè)個指令的語法吧圾浅,咱們這里學習Intel 的語法格式:“指令目的操作數(shù),源操作數(shù)飛目的操作數(shù)在左憾朴,源操作數(shù)在右狸捕,此賦值順序比較直觀。Intel 想表達的是a=b這種語序众雷,如a=b 灸拍,便是mov a, b。

以上三個步驟的機器碼按照十六進制表示為:

以上自定義的指令便是按照咱們假設(shè)的語法來生成的砾省。對于機器碼的大小株搔,由于指令不同,需要的操作數(shù)也不同纯蛾,所以機器碼大小也不同纤房。另外,機器碼中的立即數(shù)是按照x86 架構(gòu)的小端字節(jié)序?qū)懙姆撸@一點大家要注意炮姨。小端字節(jié)序是數(shù)值中的低位在低地址捌刮,高位在高地址,數(shù)位以字節(jié)為單位舒岸。

步驟2 的機器碼為01000110绅作。操作碼占1 字節(jié), CPU 識別出第1 字節(jié)的二進制01 是add 指令蛾派,知道此指令的操作數(shù)是3 個寄存器俄认,并且第1 個寄存器操作數(shù)是目的寄存器,另外兩個寄存器是源操作數(shù)(這都是我們假定的洪乍,并且是寫死在硬件中的規(guī)則眯杏,不同的指令有不同的規(guī)則,您也可以創(chuàng)造出內(nèi)存和寄存器混合作為操作數(shù)的加法指令)壳澳。于是到第2 宇節(jié)去讀取寄存器編碼岂贩,發(fā)現(xiàn)其值為二進制00 ,就是寄存器Ra 對應(yīng)的編碼巷波。接著到下一個字節(jié)處繼續(xù)讀出寄存器編碼萎津,發(fā)現(xiàn)是二進制01 ,也就是寄存器Rb, Re 同理抹镊。于是將寄存器Rb 和Re 的值相加后存入到寄存器b锉屈。

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

以上指令集的模型妹田,確實太過于簡單了,也許稱之為模型都非常勉強【楣玻現(xiàn)實中的指令格式要遠遠復雜得多鬼佣。下面我們看看目前世面上的指令集有哪些。

最早的指令集是CISC (Complex Instruction Set Computer )霜浴,意為復雜指令集計算機晶衷。從名字上看,這套指令集相當復雜,當初這套指令集問世的時候晌纫,它的研發(fā)者們都沒想過要給它起名税迷,只是因為后來出現(xiàn)了相對精簡高效的指令集,所以人們?yōu)榱思右詤^(qū)分锹漱,才將最初的這套相對復雜的指令集命名為CISC 箭养,而后來精簡高效的指令集稱為RISC (Reduced Instruction Set Computer )哥牍。

CISC 和RISC 并不是具體的指令集毕泌,而是兩種不同的指令體系,相當于指令集中的門派撼泛,是指令的設(shè)計思想。舉個例子译暂,就像中醫(yī)與西醫(yī)伯顶,中醫(yī)講究從整體上調(diào)理身體骆膝,西醫(yī)則更多的是偏向局部路克。這就是兩種不同的醫(yī)療思路精算,類似于CISC 和陽SC 這兩種指令體系疲吸。那什么是指令集呢?拿中醫(yī)舉例蹂喻,像華倫、張仲景這兩位醫(yī)圣驳概,他們雖然都是基于中醫(yī)的思想治病,但醫(yī)術(shù)各有特色稚照,水平也不盡相同,這就相當于不同的指令集斤彼。一會兒咱們會介紹具體的指令集去团。

為什么說CISC 復雜呢?

首先源哩,因為它是最早的指令集谓着,當初都是摸著石頭過河屉栓,肯定有一些瑕疵在里面句灌。其次资昧,當初的程序員都是用匯編語言開發(fā)程序叽唱,他們當然希望匯編語言強大啦,盡量多一些指令种樱,盡量一個指令能多干幾件事蒙袍,所以指令集中的指令越來越多,越來越復雜嫩挤。不過這樣的好處是程序員同學很爽害幅。最后,CISC是Intel使用的指令集岂昭,Intel公司在兼容性方面做得最好以现,指令集在發(fā)展的過程中,還要兼容過去有瑕疵的古董约啊,以至于最后的指令集變得有點“奇形怪狀”了邑遏。

作為后起之秀的RISC ,借鑒了前輩CISC 的經(jīng)驗恰矩,取其精華记盒,棄其糟柏,當然要更好更輕量啦外傅。它是怎么來的呢纪吮?

CISC 不是做得很全很強嗎,可是很多時候萎胰,程序員并不會用到那些復雜的指令和尋址方式碾盟,即使用到了,編譯器有時候為了優(yōu)化技竟,未必“全”將其編譯為復雜的形式冰肴。這就導致了CPU 中的復雜的指令和尋址方式無用武之地。根據(jù)二八定律榔组,指令集中20%的簡單指令占了程序的80% 熙尉,而指令集中80% 的復雜指令占了程序的20% 。根據(jù)這個特性搓扯,處理器及指令集被重新設(shè)計检痰,保留了那些基本常用的指令,減少了硬件電路的復雜性擅编。這樣攀细,大部分指令部能在一個時鐘周期內(nèi)完成箫踩,更有利于提升流水線的效率。而且谭贪,指令采用了定長編碼境钟,這樣譯碼工作更容易了。由于其太優(yōu)秀了俭识,后來的處理器慨削,如MIPS, ARM, Power都采用RISC 指令體系,做得最好的就是MIPS 處理器套媚,它嚴格遵守RISC 思想缚态,業(yè)界公認其優(yōu)雅。

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

雖然AMD 采用的也是x86 指令集,但Intel 可沒把硬件實現(xiàn)方法也告訴AMD 慎皱,否則AMD 的CPU 和Intel 的CPU 不就完全一樣了嗎老虫,人家Intel 也不肯呢。指令集是一套約定茫多,里面規(guī)定的是有哪些指令祈匙、指令的二進制編碼、指令格式等天揖,如何實現(xiàn)這套約定夺欲,這是硬件自己的事。打個比方宝剖,這就像和朋友約好了在某餐廳吃飯洁闰,咱是坐車去歉甚,還是走著去万细,這是咱們的事,與吃飯是無關(guān)的纸泄。說白了赖钞,在Intel 的CPU 上運行的軟件也能夠在AMD 的CPU 上運行,原因就是它們共用了同用一套指令集聘裁,也就是對二進制編碼達成了共識雪营。它們面對相同的需求,可能采取了不同的行動衡便,但都完成了任務(wù)献起。比如機器碼是b80000, Intel的CPU 經(jīng)過譯碼洋访,知道這是將0 賦值給寄存器ax,相當于匯編語言mov ax, 0 谴餐。AMD 的CPU 在譯碼時姻政,也得將此機器碼認為是將0 賦值給寄存器ax。至于它們在物理上是怎么將0 傳入寄存器ax 中的岂嗓,這是它們各自實現(xiàn)的方式汁展,與指令集無關(guān)。它們各自實現(xiàn)的方式厌殉,就叫微架構(gòu)食绿。

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

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

目前市面上常見的指令集有五種辅斟,除x86 是CISC 指令體系外, ARM芦拿、MIPS 士飒、Power、C6000 都是RISC 指令體系的指令集蔗崎。

CPU 與指令集是對應(yīng)的酵幕,一種CPU 只能識別一種指令集,所以很多CPU 都以其支持的指令集來稱呼缓苛。比如ARM 芳撒、MIPS,它們本身是CPU名稱未桥,又是指令集名稱笔刹。

ARM 主要用在手機中,作為手機的處理器冬耿。Power 是IBM 用于服務(wù)器上的處理器舌菜。C6000 是數(shù)字信號處理器,廣泛用于視頻處理亦镶。而MIPS 雖然本身很優(yōu)秀日月,但其在各領(lǐng)域起步都較晚袱瓮,并沒有廣泛應(yīng)用的領(lǐng)域。

由于MIPS 本身的優(yōu)越性爱咬,龍芯用的就是mips 指令集懂讯,有沒有人問,為什么咱們自主研發(fā)的CPU 還要用人家國外的指令集台颠?就不能也研發(fā)出一套指令集嗎褐望?能倒是能,不過語言不通用串前。就像我自己可以發(fā)明一門語言瘫里,語言本身沒什么問題,問題是我用自己發(fā)明的語言和別人交流荡碾,誰昕得懂呢谨读,誰又愿意去學這門語言呢?大家都很忙坛吁,不通用的東西沒人愿意花精力去學劳殖。如果龍芯也自立門戶創(chuàng)造新的指令集,那有誰愿意給它寫編譯器呢拨脉?即使有了編譯器哆姻,操作系統(tǒng)也要重新編譯發(fā)布,應(yīng)用程序也要重新編譯發(fā)布玫膀,指令集背后不僅是個計算機生態(tài)鏈矛缨,更重要的是全球經(jīng)濟鏈。

平時所說的編程語言帖旨,雖然其上層表現(xiàn)各異箕昭,歸根結(jié)底是要在具體的CPU 上運行的,所以必須由編譯器按照該CPU 的指奪集解阅,翻譯成符合該CPU 的指令落竹。說到這,不得不說一下交叉編譯货抄,本質(zhì)上交叉編譯就是用在A平臺上運行的編譯器述召,編譯出符合B 平臺CPU 指令集的程序,編譯出的程序直接能在B平臺上運行啦碉熄。這里的平臺指的就是CPU 指令體系結(jié)構(gòu)桨武。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肋拔,一起剝皮案震驚了整個濱河市锈津,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌凉蜂,老刑警劉巖琼梆,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件性誉,死亡現(xiàn)場離奇詭異,居然都是意外死亡茎杂,警方通過查閱死者的電腦和手機错览,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來煌往,“玉大人倾哺,你說我怎么就攤上這事」舨保” “怎么了羞海?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長曲管。 經(jīng)常有香客問我却邓,道長,這世上最難降的妖魔是什么院水? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任腊徙,我火速辦了婚禮,結(jié)果婚禮上檬某,老公的妹妹穿的比我還像新娘撬腾。我一直安慰自己,他們只是感情好恢恼,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布时鸵。 她就那樣靜靜地躺著,像睡著了一般厅瞎。 火紅的嫁衣襯著肌膚如雪饰潜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天和簸,我揣著相機與錄音彭雾,去河邊找鬼。 笑死锁保,一個胖子當著我的面吹牛薯酝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播爽柒,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼吴菠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了浩村?” 一聲冷哼從身側(cè)響起做葵,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎心墅,沒想到半個月后酿矢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體榨乎,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年瘫筐,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜜暑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡策肝,死狀恐怖肛捍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情之众,我是刑警寧澤篇梭,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站酝枢,受9級特大地震影響恬偷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜帘睦,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一袍患、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧竣付,春花似錦诡延、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逸绎,卻和暖如春惹恃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棺牧。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工巫糙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颊乘。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓参淹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親乏悄。 傳聞我的和親對象是個殘疾皇子浙值,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容