在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 學(xué)習(xí)方法與實(shí)踐 > MIPS匯編語言的特點(diǎn)

            MIPS匯編語言的特點(diǎn)

            ——
            作者: 時間:2007-10-24 來源:嵌入式在線論壇 收藏
            是CPU二進(jìn)制指令的可讀寫版本。我們在后面將有單獨(dú)的一章來講述。從來沒有接觸過的讀者在閱讀本書時可能會有一些迷惑 。 

            大多數(shù)匯編語言都是非常古板的,都是一些寄存器號碼。但是工具鏈(toolchains)可以使得使用微處理機(jī)語言變得簡單。工具鏈至少允許程序員引用一些助記符,而嚴(yán)格的匯編語言要求嚴(yán)格的數(shù)字編碼。大多我們都是用比較熟悉的C預(yù)處理器。C預(yù)處理器會把C風(fēng)格的注解去掉,而得到一個可用的匯編代碼。 

            有C預(yù)處理器的幫助,匯編程序都是用助記符來表示寄存器。助記符同時也代表了每個寄存器的用法(我們將在2.2節(jié)介紹這一點(diǎn))。 

            對於熟悉匯編語言但不熟悉的讀者,下面是一些例子。 

            /* this is a comment */ 
            #so is this 

            entrypoint: #this's a label 

            addu $1, $2, $3 # (registers) $1 = $2 + $3 

            與大多數(shù)匯編語言一樣, MIPS匯編語言也是以行為單位的。每一行的結(jié)束是一個指令的結(jié)束,并且忽略任何“#”之后的內(nèi)容,認(rèn)為是注釋。在一行里可以有多條指令。指令之間要用分號“;”隔開。 

            一個符號(label)是一個后面跟著冒號“:”的字。符號可以是任何字符串的組合。符號被用來定義一段代碼的入口和定義數(shù)據(jù)段的一個存儲位置。 

            如上所示,許多指令都是3個操作數(shù)/符(operand)。目標(biāo)寄存器在左側(cè)(注意,這一點(diǎn)與Intetel x86 正相反)。一般而言,寄存器結(jié)果和操作符的順序與C語言或其他符號語言的方式是一致的。 例如: 

            subc $1, $2, $3 

            意味著: 

            $1 = $2 - $3; 

            這方面我們就先講這么多。 

            2.2 寄存器 

            對於一個程序,可以有32個通用寄存器,分別為:$0-$31。其中,兩個,也只有兩個的使用不同于其他。 

            $0:不管你存放什么值,其返回值永遠(yuǎn)是零。 

            $31:永遠(yuǎn)存放著正常函數(shù)調(diào)用指令(jal)的返回地址。請注意call-by-registe的jalr指令可以使用任何寄存器來存放其返回地址。當(dāng)然,如不用$31,看起來程序會有點(diǎn)古怪。 

            其他方面,所有的寄存器都是一樣的。可以被用在任何一個指令中(你也可以用$0作為一個指令的目標(biāo)寄存器。當(dāng)然不管你存入什么數(shù)據(jù),數(shù)據(jù)都消失了。) 

            MIPS體系結(jié)構(gòu)下,程序計數(shù)器不是一個寄存器,其實(shí)你最好不要去那樣想。在一個具有流水線的CPU中,程序計數(shù)器的值在一個給定的時刻有多個可選值。這一點(diǎn)有點(diǎn)迷惑人。jal指令的返回地址跟隨其后的第二條指令。 

            ... 
            jal printf 
            move $4, $6 
            xxx # return here after call 

            上述的解釋是有道理的,因為緊跟蹤jal指令后面的指令,由於在delay slot(延遲位置)上--請記住,關(guān)于延遲位置的規(guī)則是該指令將在轉(zhuǎn)移目標(biāo)(如上述的printf)之前執(zhí)行。延遲位置指令經(jīng)常被用來傳遞函數(shù)調(diào)用的參數(shù)。 

            MIPS里沒有狀態(tài)碼。CPU狀態(tài)寄存器或內(nèi)部都不包含任何用戶程序計算的結(jié)果狀態(tài)信息。 

            hi和lo是與乘法運(yùn)算器相關(guān)的兩個寄存器大小的用來存放結(jié)果的地方。它們并不是通用寄存器,除了用在乘除法之外,也不能有做其他用途。但是,MIPS里定義了一些指令可以往hi和lo里存入任何值。想一想我們會發(fā)現(xiàn),這是非常有必要的當(dāng)你想要恢復(fù)一個被打斷的程序時。 

            浮點(diǎn)運(yùn)算協(xié)處理器(浮點(diǎn)加速器,F(xiàn)PA),如果存在的話,有32個浮點(diǎn)寄存器。按匯編語言的簡單約定講,是從$f0到$31。 

            實(shí)際上,對於MIPS I和MIPS II的機(jī)器,只有16個偶數(shù)號的寄存器可以用來做數(shù)學(xué)計算。當(dāng)然,它們可以既用來做單精度(32位)和雙精度(64位)。當(dāng)你做一個雙精度的運(yùn)算時,寄存器$f1存放$f0的余數(shù)。奇數(shù)號的寄存器只用來作為寄存器與FPA之間的數(shù)據(jù)傳送。 

            MIPS III CPU有32個FP寄存器。但是為了保持軟件與過去的兼容性,最好不要用奇數(shù)號的寄存器。 

            2.2.1 助記符與通用寄存器的用法 

            我們已經(jīng)描述了一些體系結(jié)構(gòu)方面的內(nèi)容,下面來介紹一些軟件方面的內(nèi)容。 

            寄存器編號 助記符 用法 
            0 zero 永遠(yuǎn)返回值為0 
            1 at 用做匯編器的暫時變量 
            2-3 v0, v1 子函數(shù)調(diào)用返回結(jié)果 
            4-7 a0-a3 子函數(shù)調(diào)用的參數(shù) 
            8-15 t0-t7 暫時變量,子函數(shù)使用時不需要保存與恢復(fù) 
            24-25 t8-t9 
            16-25 s0-s7 子函數(shù)寄存器變量。子函數(shù)必須保存和恢復(fù)使用過的變量在函數(shù)返回之前,從而調(diào)用函數(shù)知道這些寄存器的值沒有變化。 
            26,27 k0,k1 通常被中斷或異常處理程序使用作為保存一些系統(tǒng)參數(shù) 
            28 gp 全局指針。一些運(yùn)行系統(tǒng)維護(hù)這個指針來更方便的存取“static“和”extern"變量。 
            29 sp 堆棧指針 
            30 s8/fp 第9個寄存器變量。子函數(shù)可以用來做楨指針 
            31 ra 子函數(shù)的返回地□ 
            '7d 

            雖然硬件沒有強(qiáng)制性的指定寄存器使用規(guī)則,在實(shí)際使用中,這些寄存器的用法都遵循一系列約定。這些約定與硬件確實(shí)無關(guān),但如果你想使用別人的代碼,編譯器和操作系統(tǒng),你最好是遵循這些約定。 

            寄存器約定用法引人了一系列的寄存器約定名。在使用寄存器的時候,要盡量用這些約定名或助記符,而不直接引用寄存器編號。 

            1996年左右,SGI開始在其提供的編譯器中使用新的寄存器約定。這種新約定可以用來建立使用32位地址或64位地址的程序,分別叫 "n32"和"n64"。我們暫時不討論這些,將會在第10章詳細(xì)討論。 

            寄存器名約定與使用 

            *at: 這個寄存器被匯編的一些合成指令使用。如果你要顯示的使用這個寄存器(比如在異常處理程序中保存和恢復(fù)寄存器),有一個匯編directive可被用來禁止匯編器在directive之后再使用at寄存器(但是匯編的一些宏指令將因此不能再可用)。 

            *v0, v1: 用來存放一個子程序(函數(shù))的非浮點(diǎn)運(yùn)算的結(jié)果或返回值。如果這兩個寄存器不夠存放需要返回的值,編譯器將會通過內(nèi)存來完成。詳細(xì)細(xì)節(jié)可見10.1節(jié)。 


            *a0-a3: 用來傳遞子函數(shù)調(diào)用時前4個非浮點(diǎn)參數(shù)。在有些情況下,這是不對的。請參考10.1細(xì)節(jié)。 

            * t0-t9: 依照約定,一個子函數(shù)可以不用保存并隨便的使用這些寄存器。在作表達(dá)式計算時,這些寄存器是非常好的暫時變量。編譯器/程序員必須注意的是,當(dāng)調(diào)用一個子函數(shù)時,這些寄存器中的值有可能被子函數(shù)破壞掉。 

            *s0-s8: 依照約定,子函數(shù)必須保證當(dāng)函數(shù)返回時這些寄存器的內(nèi)容必須恢復(fù)到函數(shù)調(diào)用以前的值,或者在子函數(shù)里不用這些寄存器或把它們保存在堆棧上并在函數(shù)退出時恢復(fù)。這種約定使得這些寄存器非常適合作為寄存器變量或存放一些在函數(shù)調(diào)用期間必須保存原來值。 

            * k0, k1: 被OS的異?;蛑袛嗵幚沓绦蚴褂?。被使用后將不會恢復(fù)原來的值。因此它們很少在別的地方被使用。 

            * gp: 如果存在一個全局指針,它將指向運(yùn)行時決定的,你的靜態(tài)數(shù)據(jù)(static data)區(qū)域的一個位置。這意味著,利用gp作基指針,在gp指針32K左右的數(shù)據(jù)存取,系統(tǒng)只需要一條指令就可完成。如果沒有全局指針,存取一個靜態(tài)數(shù)據(jù)區(qū)域的值需要兩條指令:一條是獲取有編譯器和loader決定好的32位的地址常量。另外一條是對數(shù)據(jù)的真正存取。為了使用gp, 編譯器在編譯時刻必須知道一個數(shù)據(jù)是否在gp的64K范圍之內(nèi)。通常這是不可能的,只能靠猜測。一般的做法是把small global data (小的全局?jǐn)?shù)據(jù))放在gp覆蓋的范圍內(nèi)(比如一個變量是8字節(jié)或更小),并且讓linker報警如果小的全局?jǐn)?shù)據(jù)仍然太大從而超過gp作為一個基指針?biāo)艽嫒〉姆秶?nbsp;

            并不是所有的編譯和運(yùn)行系統(tǒng)支持gp的使用。 

            *sp: 堆棧指針的上下需要顯示的通過指令來實(shí)現(xiàn)。因此MIPS通常只在子函數(shù)進(jìn)入和退出的時刻才調(diào)整堆棧的指針。這通過被調(diào)用的子函數(shù)來實(shí)現(xiàn)。sp通常被調(diào)整到這個被調(diào)用的子函數(shù)需要的堆棧的最低的地方,從而編譯器可以通過相對於sp的偏移量來存取堆棧上的堆棧變量。詳細(xì)可參閱10.1節(jié)堆棧使用。 

            * fp: fp的另外的約定名是s8。如果子函數(shù)想要在運(yùn)行時動態(tài)擴(kuò)展堆棧大小,fp作為楨指針可以被子函數(shù)用來記錄堆棧的情況。一些編程語言顯示的支持這一點(diǎn)。匯編編程員經(jīng)常會利用fp的這個用法。C語言的庫函數(shù)alloca()就是利用了fp來動態(tài)調(diào)整堆棧的。 

            如果堆棧的底部在編譯時刻不能被決定,你就不能通過sp來存取堆棧變量,因此fp被初始化為一個相對與該函數(shù)堆棧的一個常量的位置。這種用法對其他函數(shù)是不可見的。 

            * ra: 當(dāng)調(diào)用任何一個子函數(shù)時,返回地址存放在ra寄存器中,因此通常一個子程序的最后一個指令是jr ra. 

            子函數(shù)如果還要調(diào)用其他的子函數(shù),必須保存ra的值,通常通過堆棧。 

            對於浮點(diǎn)寄存器的用法,也有一個相應(yīng)的標(biāo)準(zhǔn)的約定。我們將在7.5節(jié)。在這里,我們已經(jīng)介紹了MIPS引入的寄存 


            關(guān)鍵詞: MIPS 匯編語言

            評論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉