計(jì)算機(jī)組成與實(shí)現(xiàn) 課件 第3-5章-計(jì)算機(jī)指令;單周期CPU;多周期CPU_第1頁(yè)
計(jì)算機(jī)組成與實(shí)現(xiàn) 課件 第3-5章-計(jì)算機(jī)指令;單周期CPU;多周期CPU_第2頁(yè)
計(jì)算機(jī)組成與實(shí)現(xiàn) 課件 第3-5章-計(jì)算機(jī)指令;單周期CPU;多周期CPU_第3頁(yè)
計(jì)算機(jī)組成與實(shí)現(xiàn) 課件 第3-5章-計(jì)算機(jī)指令;單周期CPU;多周期CPU_第4頁(yè)
計(jì)算機(jī)組成與實(shí)現(xiàn) 課件 第3-5章-計(jì)算機(jī)指令;單周期CPU;多周期CPU_第5頁(yè)
已閱讀5頁(yè),還剩341頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

計(jì)算機(jī)指令計(jì)算機(jī)組成與實(shí)現(xiàn)目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序指令編碼匯編與反匯編實(shí)戰(zhàn)從C代碼到可執(zhí)行文件運(yùn)行1/6大體涉及5個(gè)環(huán)節(jié):編譯、匯編、存儲(chǔ)、加載、運(yùn)行3從C代碼到可執(zhí)行文件運(yùn)行2/6CPU不能直接執(zhí)行C源代碼,必須利用編譯器將C源代碼轉(zhuǎn)換為對(duì)應(yīng)的匯編程序C源代碼:其描述方式是適合人書寫和閱讀的匯編代碼:用更加接近CPU可以理解和執(zhí)行的語(yǔ)言編寫的程序4編譯相關(guān)內(nèi)容屬于編譯器技術(shù)范疇從C代碼到可執(zhí)行文件運(yùn)行3/6CPU也不能直接執(zhí)行匯編代碼,必須利用匯編器將匯編代碼轉(zhuǎn)換為對(duì)應(yīng)的二進(jìn)制機(jī)器碼匯編程序:每行對(duì)應(yīng)一條機(jī)器指令機(jī)器指令:由一組二進(jìn)制01串組成,是CPU可以理解與執(zhí)行的5匯編相關(guān)內(nèi)容屬于編譯器技術(shù)范疇從C代碼到可執(zhí)行文件運(yùn)行4/6C程序被編譯為一組CPU指令后,就以文件方式被存儲(chǔ)在硬盤中可執(zhí)行文件是由CPU指令及相關(guān)數(shù)據(jù)組成的由于CPU指令及相關(guān)數(shù)據(jù)以二進(jìn)制方式存儲(chǔ),因此可執(zhí)行文件是不適合人閱讀的6文件相關(guān)內(nèi)容屬于操作系統(tǒng)技術(shù)范疇從C代碼到可執(zhí)行文件運(yùn)行5/6可執(zhí)行文件要被加載到主存后才能被執(zhí)行。指令部分和數(shù)據(jù)部分會(huì)被分別加載到主存中的不同區(qū)域代碼段:這部分主存區(qū)域存儲(chǔ)的是CPU指令數(shù)據(jù)段:這部分主存區(qū)域存儲(chǔ)的是數(shù)據(jù)7將可執(zhí)行文件加載到內(nèi)存屬于操作系統(tǒng)技術(shù)范疇代碼段、數(shù)據(jù)段等內(nèi)容也與編譯器技術(shù)相關(guān)從C代碼到可執(zhí)行文件運(yùn)行6/6CPU執(zhí)行程序的基本過(guò)程就是不斷的讀取、分析和執(zhí)行指令讀取指令:CPU從主存的代碼段中讀取一條指令到內(nèi)部分析指令:CPU分析指令的功能執(zhí)行指令:CPU控制內(nèi)部的功能部件執(zhí)行相應(yīng)的操作CPU有讀、寫主存的指令負(fù)責(zé)在CPU與主存間傳輸數(shù)據(jù)8機(jī)器語(yǔ)言1/2指令:CPU理解的“單詞”指令集:CPU理解的全部“單詞”集合Q1:為什么有時(shí)不同的計(jì)算機(jī)使用相同的指令集?例如:iPhone與iPad使用相同的指令集(都是ARM)Q2:為什么有時(shí)不同的計(jì)算機(jī)使用不同的指令集?例如:iPhone與Macbook使用不同的指令集(前者是ARM,后者是X86)9ISA~InstructionSetArchitecture機(jī)器語(yǔ)言2/2如果只有一種ISA可以很好的利用公共軟件,如編譯器、操作系統(tǒng)等如果有多種ISA針對(duì)不同的應(yīng)用可以選擇更適用的ISA不同的指令集有不同的設(shè)計(jì)平衡性考慮功能、性能、存儲(chǔ)器、功耗、復(fù)雜度。。。會(huì)激發(fā)競(jìng)爭(zhēng)和創(chuàng)新10為什么要學(xué)習(xí)匯編?在更深層次理解計(jì)算機(jī)行為學(xué)習(xí)如何寫更緊湊和有效的代碼某些情況下,手工編碼的優(yōu)化水平比編譯器高對(duì)于資源緊張的應(yīng)用,可能只適合手工匯編例如:分布式傳感器應(yīng)用為了降低功耗和芯片大小,甚至沒(méi)有OS和編譯器11RISCComplexInstructionSetComputing(CISC)指令集設(shè)計(jì)早期階段傾向于:應(yīng)用有什么操作模式,就增加對(duì)應(yīng)的指令。這導(dǎo)致了CISCReducedInstructionSetComputing(RISC)另一種對(duì)立的設(shè)計(jì)哲學(xué)自然界存在2-8定律。程序也類似,為什么?RISC的指導(dǎo)思想1)加速大概率事件2)簡(jiǎn)單意味著更容易設(shè)計(jì)、電路頻率更高3)簡(jiǎn)單功能由硬件實(shí)現(xiàn);復(fù)雜功能(由大量小功能組成)交給軟件處理隱含的物理背景:復(fù)雜的功能也是小概率的12RISC設(shè)計(jì)原則指導(dǎo)思想:CPU越簡(jiǎn)單,性能越高設(shè)計(jì)目標(biāo):減少指令數(shù)量,去除復(fù)雜指令(等效于降低復(fù)雜度)RISC的基本策略指令定長(zhǎng):所有指令都占用32位(1個(gè)字)

降低了從存儲(chǔ)器中讀取指令的復(fù)雜度簡(jiǎn)化指令尋址模式:以基地址+偏移為主

降低了從主存中讀取操作數(shù)的復(fù)雜度ISA的指令不僅數(shù)量少,而且簡(jiǎn)單

降低了指令執(zhí)行的復(fù)雜度只有l(wèi)oad與store兩類指令能夠訪存

例如,不允許寄存器+存儲(chǔ)器或存儲(chǔ)器+存儲(chǔ)器把復(fù)雜留給編譯編譯器將高層語(yǔ)言復(fù)雜語(yǔ)句轉(zhuǎn)換為若干簡(jiǎn)單的匯編指令13主流的ISAIntel80x86PC、服務(wù)器、筆記本ARM(AdvancedRISCMachine)手機(jī)、平板出貨量最大的RISC:是x86的20倍PowerPCIBM/Motorola/Apple聯(lián)盟的產(chǎn)物航空電子設(shè)備:飛控、機(jī)載雷達(dá)等網(wǎng)絡(luò)設(shè)備:交換機(jī)、路由器引擎控制器14為什么選擇MIPS真實(shí):工業(yè)界實(shí)際使用的CPU是設(shè)計(jì)師在實(shí)踐中多次迭代、反復(fù)權(quán)衡的產(chǎn)物學(xué)習(xí)標(biāo)準(zhǔn)就是在學(xué)習(xí)設(shè)計(jì)師的思考方法與過(guò)程簡(jiǎn)明:類別有限、結(jié)構(gòu)簡(jiǎn)單、層次清晰,易于實(shí)現(xiàn)MIPS是RISC的典型代表生態(tài):軟件開(kāi)發(fā)環(huán)境豐富,易于學(xué)習(xí)和實(shí)踐多種模擬器、C編譯等15目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令基本格式指令集與匯編程序指令編碼匯編與反匯編實(shí)戰(zhàn)MIPS指令1/2指令的一般性語(yǔ)法格式:1個(gè)操作符,3個(gè)操作數(shù)opdst,src1,src2op:指令的基本功能dst:保存結(jié)果的寄存器(“destination”)src1:第1個(gè)操作數(shù)(“source1”)src2:第2個(gè)操作數(shù)(“source2”)固定的格式:

有助于人的記憶和書寫;

有助于使得硬件簡(jiǎn)單硬件越簡(jiǎn)單,延遲就越小,時(shí)鐘頻率就越高17

MIPS指令2/2每條指令只有1個(gè)操作每行寫一條指令很多指令與C運(yùn)算高度相關(guān)如:=,+,-,*,/,&,|一行C代碼會(huì)對(duì)應(yīng)多條指令18目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)第1類操作數(shù):寄存器指令集與匯編程序指令編碼匯編與反匯編實(shí)戰(zhàn)計(jì)算機(jī)硬件的操作數(shù)C程序:變量的數(shù)量?jī)H僅受限于內(nèi)存容量程序員通常認(rèn)為內(nèi)存“無(wú)限大”,故聲明變量時(shí)一般不考慮變量的數(shù)量ISA:有一組數(shù)量有限且固定的操作數(shù),稱之為寄存器寄存器被內(nèi)置在CPU內(nèi)部寄存器的優(yōu)勢(shì):速度極快(工作速度小于1ns)寄存器的劣勢(shì):數(shù)量少20寄存器1/2MIPS寄存器數(shù)量:32每個(gè)寄存器的寬度都是32位寄存器沒(méi)有類型(即無(wú)正負(fù))根據(jù)指令的功能來(lái)解讀寄存器值的正負(fù)即32位編碼是按無(wú)符號(hào)還是符號(hào)解讀,取決于指令寄存器數(shù)量的是設(shè)計(jì)均衡的體現(xiàn)均衡的要素:性能與可用性數(shù)量少:結(jié)構(gòu)簡(jiǎn)單,速度快,能夠存儲(chǔ)在CPU內(nèi)的數(shù)據(jù)少數(shù)量多:結(jié)構(gòu)復(fù)雜,速度慢,能夠存儲(chǔ)在CPU內(nèi)的數(shù)據(jù)多21預(yù)留思考題MIPS寄存器為什么不是16個(gè),也不是64個(gè)?!寄存器2/2寄存器編號(hào):0~31寄存器表示:$x(x為0~31),即$0~$31寄存器名字程序員變量寄存器$s0-$s7←→$16-$23臨時(shí)變量寄存器$t0-$t7←→$8-$15$t8-$t9←→$8-$1522注意使用寄存器名字會(huì)讓代碼可讀性更好編號(hào)名稱用途0$zero常量01$at匯編器保留2-3$v0~$v1返回值4-7$a0~$a4參數(shù)8-15$t0-$t7臨時(shí)變量16-23$s0-$s7程序變量24-25$t8-$t9臨時(shí)變量26-27$k0-$k1操作系統(tǒng)臨時(shí)變量28$gp全局指針29$sp棧指針30$fp幀框架指針31$ra返回地址本課程要學(xué)習(xí)的寄存器MIPS指令示例1/2假設(shè):變量a,b和c分別存儲(chǔ)在$s1,$s2和$s3a←→$s1,b←→$s2,c←→$s3整數(shù)加法指令C:

a=b+cMIPS:

add$s1,$s2,$s3整數(shù)減法指令C:

a=b-cMIPS:

sub$s1,$s2,$s323MIPS指令示例2/2假設(shè):x←→$s0,a←→$s1,b←→$s2,c←→$s3,d←→$s4C語(yǔ)句:x=(a+b)-(c+d);MIPS匯編程序片段$t1,$t2:臨時(shí)變量寄存器注釋:提高可讀性;幫助追蹤寄存器/變量的分配與使用#:是注釋語(yǔ)句的開(kāi)始241add$t1,$s3,$s4#t1=c+d2add$t2,$s1,$s2#t2=a+b3sub$s0,$t2,$t1#a=(a+b)-(c+d)執(zhí)行序MIPS匯編程序注釋

0號(hào)寄存器由于0在程序中的頻度極高,為此MIPS設(shè)置了0號(hào)寄存器表示方法:$0或$zero值恒為0:讀出的值恒為0;寫入的值被丟棄指令的dst為$0:指令使用本身無(wú)錯(cuò),但執(zhí)行時(shí)沒(méi)有實(shí)際意義示例25假設(shè):a←→$s1,b←→$s2,c←→$s3,d←→$s41add$s3,$0,$0#c=02add$s1,$s2,$0#a=b目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)第2類操作數(shù):立即數(shù)指令集與匯編程序指令編碼匯編與反匯編實(shí)戰(zhàn)立即數(shù)指令中出現(xiàn)的常量數(shù)值被稱為立即數(shù)語(yǔ)法格式opdst,src,imm立即數(shù)替代了第2個(gè)操作數(shù)示例27假設(shè):a←→$s1,b←→$s2,c←→$s3,d←→$s41addi$s1,$s2,5#a=b+52addi$s3,$s3,1#c++問(wèn)題為什么MIPS不設(shè)置subi指令?*subi:減立即數(shù)immediate~立即數(shù)目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)第3類操作數(shù):主存單元指令集與匯編程序指令編碼匯編與反匯編實(shí)戰(zhàn)主存單元僅使用寄存器的挑戰(zhàn):有限的寄存器無(wú)法滿足無(wú)限的變量需求1)變量的個(gè)數(shù)無(wú)限:理論上,程序員可以定義任意多變量2)變量的容量巨大:如數(shù)組這樣的大型數(shù)據(jù)結(jié)構(gòu)解決問(wèn)題途徑:主存絕大多數(shù)變量(包括數(shù)據(jù))存儲(chǔ)在主存中需要使用時(shí)再將其加載至寄存器中CPU訪問(wèn)主存,需要解決問(wèn)題:1)CPU如何看待主存的?這就是存儲(chǔ)視圖2)CPU如何定位某個(gè)主存單元?這就是尋址方式3)CPU如何訪問(wèn)訪問(wèn)主存單元?29主存的抽象模型1/3主存:可以被抽象為一個(gè)數(shù)組概念1:主存單元的顆粒度字節(jié):是存儲(chǔ)器最常用的存儲(chǔ)單位概念2:地址主存單元的編號(hào)就是地址,等同于數(shù)組下標(biāo)對(duì)于4GB主存4GB主存共有4G個(gè)字節(jié),即有4G個(gè)存儲(chǔ)單元4G個(gè)存儲(chǔ)單元對(duì)應(yīng)的地址位數(shù)為32位232=4G地址范圍:0000_0000h至FFFF_FFFFhFFFF_FFFFFFFF_FFFEFFFF_FFFDFFFF_FFFCABFFFF_FFFBCDFFFF_FFFA主存容量EFFFFF_FFF94GB01FFFF_FFF8~0000_00030000_00020000_00010000_0000字節(jié)地址bit~比特,byte~字節(jié),word~字主存的抽象模型2/3概念3:CPU字長(zhǎng)CPU字長(zhǎng)一般是指CPU一條指令可以計(jì)算的數(shù)據(jù)的寬度例如MIPS的字長(zhǎng)是32位,即單條MIPS指令可以計(jì)算的數(shù)據(jù)為32位注意:CPU字長(zhǎng)只是限制了單條指令的計(jì)算能力,但是完全可以通過(guò)組合多條指令及必要的存儲(chǔ)單元來(lái)計(jì)算更大位數(shù)的數(shù)據(jù)示例:大數(shù)乘法提示:用一個(gè)數(shù)組的每個(gè)單元來(lái)存儲(chǔ)每一位數(shù)字;然后組織循環(huán),利用最基本的數(shù)學(xué)運(yùn)算知識(shí)獨(dú)立計(jì)算每位結(jié)果及其進(jìn)位158703333333333333333X26666666666666666用16個(gè)單元(16字節(jié))的數(shù)組計(jì)算乘法**循環(huán)16次,每次僅計(jì)算3*2=6主存的抽象模型3/3

FFFF_FFFCFFFF_FFF8ABCDEF01~0000_00080000_00040000_0000字節(jié)3字節(jié)2字節(jié)1字節(jié)0字內(nèi)偏移:0字內(nèi)偏移:1字內(nèi)偏移:2字內(nèi)偏移:30000_000B0000_000A0000_00090000_0008字地址地址的表示方式

FFFF_FFFFFFFF_FFFEFFFF_FFFDFFFF_FFFCB2ABFFFF_FFFBCDFFFF_FFFAPEFFFFF_FFF9B101FFFF_FFF8~0000_00030000_00020000_00010000_0000字節(jié)地址baseaddress~基地址,offset~偏移“基地址+偏移”的優(yōu)點(diǎn)一致:與數(shù)據(jù)結(jié)構(gòu)的訪問(wèn)方式高度一致示例1:數(shù)組單元A[5]的地址=數(shù)組首地址+4×5示例2:以B.z為例,可以推算出z與B的起始地址的距離為了便于分配存儲(chǔ)器,編譯器會(huì)把x、y、z連續(xù)存儲(chǔ)統(tǒng)一:可以用某個(gè)固定base與不同的offset計(jì)算得到任意地址靈活:不同的{base,offset}組合可以對(duì)應(yīng)同一個(gè)地址,為軟件編程帶來(lái)很大的靈活性示例:可以從數(shù)組起始向末尾遍歷(base為數(shù)組第0單元地址,offset為正),也可以從數(shù)組末尾向起始遍歷(base為數(shù)組最后單元地址,offset為負(fù))intA[100];struct{

intx;shorty;charz;}B;數(shù)據(jù)傳輸指令1/2語(yǔ)法格式opreg,off(base)reg:寫入或讀出的寄存器base:存儲(chǔ)基地址的寄存器由于存儲(chǔ)的是地址信息,因此base的值被作為無(wú)符號(hào)數(shù)off:以字節(jié)為單位的偏移量off是立即數(shù),可正可負(fù)讀寫的存儲(chǔ)單元的實(shí)際地址=base+off35offset~偏移數(shù)據(jù)傳輸指令2/2加載字:lw(LoadWord)讀取地址為base+off的主存單元,然后寫入reg存儲(chǔ)字:sw(StoreWord)讀取reg,然后寫入地址為base+off的存儲(chǔ)單元示例36假設(shè):A[]←→$s3,a←→$s01lw$t0,12($s3)#$t0=A[3]2add$t0,$s2,$t0#$t0=A[3]+a3sw$t0,40($s3)#A[10]=A[3]+a注意lw/sw讀寫對(duì)象是字,因此偏移量必須是4的倍數(shù)intA[100];A[10]=A[3]+a;主存單元使用的限制MIPS不支持主存單元參與運(yùn)算例如以下用法均是錯(cuò)誤用法add$t0,$s1,0($s2)sub$t0,0($s2),12MIPS支持的運(yùn)算寄存器—寄存器:寄存器與寄存器運(yùn)算,結(jié)果寫入寄存器寄存器—立即數(shù):寄存器與立即數(shù)運(yùn)算,結(jié)果寫入寄存器37注意在MIPS中,主存單元僅能與寄存器進(jìn)行數(shù)據(jù)交換。之所以這樣設(shè)計(jì),是為了便于設(shè)計(jì)流水線CPU。寄存器vs.主存變量比寄存器多怎么辦?把最常用的變量保存在寄存器中其他不常用的變量保存在主存中為什么不把變量都放在存儲(chǔ)器中?寄存器比存儲(chǔ)器快100~500倍38目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序匯編程序基本結(jié)構(gòu)指令編碼匯編與反匯編實(shí)戰(zhàn)代碼段與數(shù)據(jù)段程序由指令和數(shù)據(jù)構(gòu)成,分別存儲(chǔ)在主存中的不同區(qū)域所有程序都有指令;絕大多數(shù)程序都會(huì)包含數(shù)據(jù)分離存儲(chǔ)是為了防止兩者之間相互干擾代碼段:存放程序中指令序列的一塊內(nèi)存區(qū)域數(shù)據(jù)段:存儲(chǔ)程序中全局變量的一塊內(nèi)存區(qū)域代碼段數(shù)據(jù)段空間大小有程序中的指令部分決定程序運(yùn)行前就已經(jīng)確定由程序中的全局變量部分決定程序運(yùn)行前就已經(jīng)確定讀寫權(quán)限只讀*(ReadOnly)可讀可寫(Read/Write匯編關(guān)鍵字.text.data*某些CPU允許代碼段為可寫,即允許程序自修改(self-modifyingcode)匯編程序的基本結(jié)構(gòu)關(guān)鍵字“.text”和“.data”用來(lái)區(qū)分程序的數(shù)據(jù)部分和代碼部分“.text”與“.data”本質(zhì)上是代表基地址的標(biāo)號(hào)CPU的內(nèi)存布局是確定的,即代碼段、數(shù)據(jù)段在主存中的基地址是確定的根據(jù)數(shù)據(jù)段和代碼段的基地址,匯編器能推算.data后面的各全局變量以及.text后面的各指令對(duì)應(yīng)的相對(duì)偏移,也自然可以計(jì)算相應(yīng)的絕對(duì)地址示例:ori指令的偏移量是41234567.data

str:.asciiz"1234+4321"

.text

lui$s7,0x1001

ori$s7,$s7,0x0數(shù)據(jù)段定義一個(gè)全局變量

正文段目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序全局變量聲明指令編碼匯編與反匯編實(shí)戰(zhàn)全局變量聲明的基本要素全局變量位于“.data”關(guān)鍵字之后要素1)變量名可以包含字母、數(shù)字、下劃線等;但不能有空格、+、-等符號(hào)要素2)關(guān)鍵字用于定義變量的類型要素3)值用于定義變量的值示例:str是一個(gè)字符串變量,其值為“1234+4321”.data

str:.asciiz

"1234+4321"

常見(jiàn)變量類型1/2與C語(yǔ)言不同,匯編語(yǔ)言關(guān)注的是變量的存儲(chǔ)類型,即一個(gè)變量需要占用多少字節(jié)匯編語(yǔ)言的變量類型都是無(wú)符號(hào)的關(guān)鍵字基本用途.byte聲明8位變量.half聲明16位變量.word聲明32位變量.ascii聲明字符串。但字符串結(jié)尾沒(méi)有’\0’.asciiz聲明字符串。但字符串結(jié)尾有’\0’.space為一個(gè)變量預(yù)留指定的字節(jié)數(shù)常見(jiàn)變量類型2/2注意匯編代碼與C代碼的區(qū)別例如half,匯編代碼中只知道占據(jù)2個(gè)字節(jié);C代碼無(wú)論是short還是unsignedshort,都與之對(duì)應(yīng)例如數(shù)組array,匯編中只定義了100個(gè)單元,但C語(yǔ)言還能明確其是char而不是unsignedchar類型匯編代碼C代碼12345678.datastr:.asciiz"1234+4321"half:.space2i:.word0xAABBCCDDarray:.space100

.text...

charstr[]="1234+432";shorthalf;inti=0xAABBCCDD;chararray[100];

voidmain(void)...目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序讀/寫存儲(chǔ)器指令編碼匯編與反匯編實(shí)戰(zhàn)lb:讀字節(jié)1/3lb格式:lbrt,offset(base)lb功能:從以編號(hào)為base的寄存器為基地址、offset為偏移的地址單元處,讀取一個(gè)字節(jié),然后將其寫入編號(hào)為rt的寄存器以lb指令功能為例,可以看出自然語(yǔ)言描述方式的缺陷1)不精確,易引起二義性例如,讀出的是1個(gè)字節(jié),要寫入的寄存器是4個(gè)字節(jié),兩者是何種對(duì)應(yīng)關(guān)系?2)不簡(jiǎn)練如果希望表達(dá)的無(wú)二義,則自然語(yǔ)言表達(dá)方式往往會(huì)非常繁瑣RTL是一種形式化方式描述指令功能的語(yǔ)言RTL:RegisterTransferLanguage它用于描述從寄存器到寄存器之間的行為注意所有讀/寫存儲(chǔ)器指令的offset都是以字節(jié)為單位的lb:讀字節(jié)2/3lb格式:lbrt,offset(base)RTL描述的lb功能R[]:對(duì)應(yīng)MIPS的32個(gè)寄存器這些寄存器有時(shí)也被稱為通用寄存器(GeneralPurposeRegister)示例:R[base]代表標(biāo)號(hào)為base的寄存器M[]:對(duì)應(yīng)主存示例:M[5]代表地址為5的主存單元R[rt]

M[R[base]+offset]注意lb的功能是讀取字節(jié),但上述描述并未明確表達(dá)這一點(diǎn)這就必須進(jìn)一步明確描述lb的具體操作細(xì)節(jié)lb:讀字節(jié)3/3RTL描述lb的更多功能細(xì)節(jié)sign_ext():代表符號(hào)擴(kuò)展第1步:計(jì)算主存單元的地址第2步:從主存中讀取的一個(gè)字第3步:計(jì)算字內(nèi)正確的字節(jié)偏移第4步:將字節(jié)寫入寄存器相對(duì)自然語(yǔ)言描述方式,RTL描述具有準(zhǔn)確、無(wú)二義的特點(diǎn)Addr

R[base]+sign_ext(offset)memword

M[Addr]byte

Addr1..0R[rt]

sign_ext(memword7+8*byte..8*byte)注意第2步之所以讀取的是字而不是字節(jié),是使得CPU與主存間始終以32位寬度交換數(shù)據(jù),從而簡(jiǎn)化數(shù)據(jù)傳輸方式sb:寫字節(jié)sb的功能與lb恰好相反,用于將寄存器的最低字節(jié)寫入主存單元sb格式:sbrt,offset(base)sb的RTL描述sb的RTL細(xì)節(jié)描述M[R[base]+offset]

R[rt]Addr

R[base]+sign_ext(offset)byte

Addr1..0M[Addr]7+8*byte..8*byte

R[rt]7..0lb/sb的用法1/3示例:假設(shè)*($s0)=0x00000180 lb$s1,1($s0)#$s1=0x00000001B3B2B1B000000180S0XXXXS1RegisterFileMemory0000_000100000001lb/sb的用法2/3示例:假設(shè)*($s0)=0x00000180 lb$s1,1($s0)#$s1=0x00000001 lb$s2,0($s0)#$s2=0xFFFFFF80B3B2B1B000000180S0XXXXS100000001S2RegisterFileMemory1000_0000FFFFFF80lb/sb的用法3/3示例:假設(shè)*($s0)=0x00000180 lb$s1,1($s0)#$s1=0x00000001 lb$s2,0($s0)#$s2=0xFFFFFF80 sb$s2,2($s0)#*($s0)=0x00800180B3B2B1B000000180S0XXXXS100000001S2FFFFFF80RegisterFileMemory8080加載和存儲(chǔ)指令匯總字操作:偏移必須是4的倍數(shù)lw、sw半字操作:偏移必須是2的倍數(shù)lh、lhush字節(jié)操作lb、lbusb注意lbu/lhu:沒(méi)有符號(hào)擴(kuò)展54大/小印第安大印第安:最高有效字節(jié)在字內(nèi)的最低地址小印第安:最高有效字節(jié)在字內(nèi)的最高地址MIPS:同時(shí)支持2種類型本課程用小印第安msblsb3 2 1 0littleendian0 1 2 3bigendianendianness~字節(jié)順序55目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序算術(shù)運(yùn)算指令編碼匯編與反匯編實(shí)戰(zhàn)算術(shù)運(yùn)算指令概述計(jì)算機(jī)最重要的功能就是完成加、減、乘及除等算術(shù)運(yùn)算幾乎所有的高級(jí)程序設(shè)計(jì)都支持這些算術(shù)運(yùn)算MIPS為此設(shè)置相應(yīng)的算術(shù)運(yùn)算指令除從運(yùn)算功能角度分類,還可從操作數(shù)角度分類寄存器—寄存器型(R-R):參與運(yùn)算的2個(gè)操作數(shù)都是寄存器,結(jié)果寫入寄存器寄存器—立即數(shù)型(R-I):參與運(yùn)算的2個(gè)操作數(shù)一個(gè)是寄存器,另一個(gè)是立即數(shù),結(jié)果寫入寄存器加法和減法加法有4條指令:add,addu,addi,addiu減法有2條指令:sub,subu指令功能格式描述示例add加法

(檢測(cè)溢出)addrd,rs,rtR[rd]

R[rs]+R[rt]add$s1,$s2,$s3addu加法(不檢測(cè)溢出)addrd,rs,rtR[rd]

R[rs]+R[rt]addu$s1,$s2,$s3addi立即數(shù)加(檢測(cè)溢出)addirt,rs,imm16R[rt]

R[rs]+sign_ext(imm16)addi$s1,$s2,-3addiu立即數(shù)加(不檢測(cè)溢出)addiurt,rs,imm16R[rt]

R[rs]+sign_ext(imm16)addiu$s1,$s2,3sub減法(檢測(cè)溢出)subrd,rs,rtR[rd]

R[rs]-R[rt]sub$s1,$s2,$s3subu減法(不檢測(cè)溢出)subrd,rs,rtR[rd]

R[rs]-R[rt]subu$s1,$s2,$s3問(wèn)題為什么沒(méi)有subi和subiu?算術(shù)溢出1/2復(fù)習(xí):當(dāng)計(jì)算結(jié)果的位數(shù)超出計(jì)算機(jī)硬件的實(shí)際能保存的位數(shù),即為溢出換言之,即沒(méi)有足夠的位數(shù)保存運(yùn)算結(jié)果MIPS會(huì)檢測(cè)溢出(并且當(dāng)溢出發(fā)生時(shí)產(chǎn)生錯(cuò)誤)有unsigned關(guān)鍵字的算術(shù)類指令忽略溢出59檢測(cè)溢出不檢測(cè)溢出adddst,src1,src2addudst,src1,src2addidst,src1,src2addiudst,src1,src2sub

dst,src1,src2subudst,src1,src2算術(shù)溢出1/2示例60#$s0=0x80000000,$s1=0x1add$t0,$s0,$s0#溢出(出錯(cuò))addu$t1,$s0,$s0#$t1=0addi$t2,$s0,-1#溢出(出錯(cuò))addiu$t3,$s0,-1#$t3=0x7FFFFFFFsub$t4,$s0,$s1#溢出(出錯(cuò))subu$t5,$s0,$s1#$t5=0x7FFFFFFF復(fù)習(xí):這是最小的負(fù)數(shù)!乘除法指令乘除法指令計(jì)算結(jié)果:不是直接寫入32個(gè)通用寄存器,而是保存在2個(gè)特殊寄存器HI與LO用2條專用指令讀寫HI/LO“movefromHI”(mfhidst)“movefromLO”(mflodst)Multiplication(mult)multsrc1,src2src1*src2:LO保存結(jié)果的低32位,HI保存結(jié)果的高32位Division(div)divsrc1,src2src1/src2:LO保存商,HI保存余數(shù)61quotient~商;remainder~余數(shù)乘除法指令示例:用div求模#$s2=$s0mod$s1mod:div$s0,$s1#LO=$s0/$s1mfhi$s2 #HI=$s0mod$s162目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序邏輯運(yùn)算(位運(yùn)算)指令編碼匯編與反匯編實(shí)戰(zhàn)位運(yùn)算指令假設(shè):a$s1,b$s2,c$s364指令CMIPS與a=b&c;and$s1,$s2,$s3與立即數(shù)a=b&0x1;andi$s1,$s2,0x1或a=b|c;or$s1,$s2,$s3或立即數(shù)a=b|0x5;ori$s1,$s2,0x5或非a=~(b|c);nor$s1,$s2,$s3異或a=b^c;xor$s1,$s2,$s3異或立即數(shù)a=b^0xF;xori$s1,$s2,0xF目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序分支指令指令編碼匯編與反匯編實(shí)戰(zhàn)基本的決策機(jī)制C:有if-else,for,while,do-while等語(yǔ)句塊決策機(jī)制:根據(jù)條件轉(zhuǎn)移并執(zhí)行相應(yīng)的語(yǔ)句塊MIPS:通過(guò)標(biāo)號(hào)機(jī)制來(lái)實(shí)現(xiàn)轉(zhuǎn)移MIPS沒(méi)有語(yǔ)句塊的概念,只有地址的概念每條指令都對(duì)應(yīng)一個(gè)word地址為了提高可讀性,匯編程序使用標(biāo)號(hào)來(lái)標(biāo)記其后的指令的地址標(biāo)號(hào)是由字符串+’:’組成。例如:ForBegin:匯編語(yǔ)言再通過(guò)跳轉(zhuǎn)機(jī)制跳轉(zhuǎn)到標(biāo)號(hào)處,從而實(shí)現(xiàn)轉(zhuǎn)移注意C也有類似的機(jī)制,例如goto,但被認(rèn)為是不好的編程風(fēng)格66label~標(biāo)號(hào)分支指令BranchIfEqual(beq):相等時(shí)轉(zhuǎn)移beqreg1,reg2,label如果reg1的值=reg2的值,則轉(zhuǎn)移至label處執(zhí)行BranchIfNotEqual(bne):不等時(shí)轉(zhuǎn)移bnereg1,reg2,label如果reg1的值≠reg2的值,則轉(zhuǎn)移至label處執(zhí)行Jump(j):無(wú)條件轉(zhuǎn)移jlabel無(wú)條件轉(zhuǎn)移至label處執(zhí)行對(duì)應(yīng)C的goto機(jī)制67用beq構(gòu)造if-else與C不同之處:b類指令是條件為TRUE則轉(zhuǎn)移,F(xiàn)ALSE則順序!68if(i==j){a=b/*then*/}else{a=-b/*else*/}執(zhí)行邏輯如果TRUE,執(zhí)行THEN語(yǔ)句塊如果FALSE,執(zhí)行ELSE語(yǔ)句塊MIPS(beq):#i$s0,j$s1#a$s2,b$s3beq$s0,$s1,thenelse:sub$s2,$0,$s3jendthen:add$s2,$s3,$0end:???可以去除該標(biāo)號(hào)???C代碼:用bne構(gòu)造if-else與C不同之處:beq/bne構(gòu)造if-else是條件為TRUE則轉(zhuǎn)移!69if(i==j){a=b/*then*/}else{a=-b/*else*/}執(zhí)行邏輯如果TRUE,執(zhí)行THEN語(yǔ)句塊如果FALSE,執(zhí)行ELSE語(yǔ)句塊MIPS(bne):#i$s0,j$s1#a$s2,b$s3bne$s0,$s1,elsethen:add$s2,$s3,$0jendelse:sub$s2,$0,$s3end:??????C代碼:switch-case大多數(shù)高級(jí)程序設(shè)計(jì)語(yǔ)言具有switch-case語(yǔ)句結(jié)構(gòu)在MIPS匯編程序中,可以用一組b類指令來(lái)構(gòu)造switch-case1234567891011121314151617switch()case條件1

語(yǔ)句塊1case條件2

語(yǔ)句塊2…case條件N

語(yǔ)句塊Nb類,$條件1,Case1b類,$條件2,Case2…b類,$條件N,CaseNjSwitchEndCase1:

語(yǔ)句塊1jSwitchEndCase2:

語(yǔ)句塊2jSwitchEnd…CaseN:

語(yǔ)句塊NjSwitchEnd

SwitchEnd:注意1每個(gè)case后面都需要一條j指令注意2該MIPS匯編框架沒(méi)有考慮default情況更多分支指令與0比較的分支指令(簡(jiǎn)稱bxxz類指令)blez(小于等于0轉(zhuǎn)移)bgtz(大于0轉(zhuǎn)移)bltz(小于0轉(zhuǎn)移)bgez(大于等于0轉(zhuǎn)移)bxxz類指令格式均為:bxxz

rs,label由于bxxz指令固定與$0比較,因此指令中無(wú)需再描述$0了循環(huán)C語(yǔ)言有3種循環(huán):for,while,do…while3種語(yǔ)句是等價(jià)的,即任意一種循環(huán)都可以改寫為其他兩種循環(huán)MIPS只需要一種決策機(jī)制即可核心:根據(jù)條件轉(zhuǎn)移72循環(huán)實(shí)戰(zhàn):從C到MIPS1/5實(shí)例:字符串賦值C代碼

/*字符串復(fù)制

*/ char*p,*q; while((*q++=*p++)!=‘\0’);代碼結(jié)構(gòu)有什么特征單一的while循環(huán)退出循環(huán)是一個(gè)相等測(cè)試73循環(huán)實(shí)戰(zhàn):從C到MIPS2/5實(shí)例:字符串賦值C代碼

/*字符串復(fù)制

*/ char*p,*q; while((*q++=*p++)!=‘\0’);代碼結(jié)構(gòu)有什么特征?單一的while循環(huán)退出循環(huán)是一個(gè)相等測(cè)試74Q:2種寫法的區(qū)別在哪里?

while(*p) *q++=*p++;循環(huán)實(shí)戰(zhàn):從C到MIPS3/5STEP1:構(gòu)造循環(huán)的框架#字符串復(fù)制#p$s0,q

$s1(p和q都是指針)Loop:lb$t0,0($s0)#$t0=*psb$t0,0($s1)#*q=$t0addi$s0,$s0,1 #p=p+1addi$s1,$s1,1#q=q+1beq$t0,$0,Exit#if*p==0,gotoExit

jLoop#gotoLoopExit:

#Ncharsinp=>N*6instructions75#$t0=*p#*q=$t0#p=p+1#q=q+1#if*p==0,gotoExit#gotoLoop循環(huán)實(shí)戰(zhàn):從C到MIPS4/5STEP2:構(gòu)造循環(huán)主體#字符串復(fù)制#p$s0,q

$s1(p和q都是指針)Loop:lb$t0,0($s0)sb$t0,0($s1)addi$s0,$s0,1 addi$s1,$s1,1beq$t0,$0,Exit

jLoopExit:

#Ncharsinp=>N*6instructions76#$t0=*p#*q=$t0#p++#q++#if$t0==0,gotoExit#gotoLoopQ1個(gè)字符需要6條指令。能否優(yōu)化?循環(huán)實(shí)戰(zhàn):從C到MIPS5/5優(yōu)化代碼(減少了1條指令)#字符串復(fù)制#p$s0,q

$s1(p和q都是指針)Loop:lb$t0,0($s0)

sb$t0,0($s1)

addi$s0,$s0,1

addi$s1,$s1,1

bne$t0,$0,Loop#Ncharsinp=>N*6instructions77#$t0=*p#*q=$t0#p=p+1#q=q+1#if*p!=0,gotoLoop不等式不等關(guān)系:<,<=,>,>=MIPS:用增加1條額外的指令來(lái)支持所有的比較SetonLessThan(slt)sltdst,src1,src2如果src1<src2,dst寫入1,否則寫入與bne,beq,and$0組合即可實(shí)現(xiàn)所有的比較78不等式實(shí)現(xiàn)<79C代碼MIPS匯編if(a<b){.../*then*/}(假設(shè):a$s0,b$s1)slt$t0,$s0,$s1

#$t0=1ifa<b#$t0=0ifa>=bbne$t0,$0,then

#gotothen#if$t0≠0不等式實(shí)現(xiàn)>=Q:請(qǐng)自行完成交換src1與src2分別用beq與bne80C代碼MIPS匯編if(a>=b){.../*then*/}(假設(shè):a$s0,b$s1)slt$t0,$s0,$s1#$t0=1ifa<b#$t0=0ifa>=bbeq$t0,$0,then

#gotothen#if$t0=0不等式

slt的3種變形sltudst,src1,src2:無(wú)符號(hào)數(shù)比較sltidst,src,imm:

與常量比較sltiudst,src,imm:與無(wú)符號(hào)常量比較示例:addi$s0,$0,-1#$s0=0xFFFFFFFFslti$t0,$s0,1#$t0=1sltiu$t1,$s0,1#$t1=081#$t0=1#$t1=0不等式

82原條件等價(jià)條件指令用法結(jié)果寄存器的0/1值含義a<b

slt

結(jié)果寄存器,a,b0:原條件為假1:原條件為真a>bb<aslt

結(jié)果寄存器,b,a0:原條件為假1:原條件為真a<=bslt

結(jié)果寄存器,b,a0:原條件為真1:原條件為假a>=bslt

結(jié)果寄存器,a,b0:原條件為真1:原條件為假[AD]MIPS的Signed與Unsigned術(shù)語(yǔ)Signed與Unsigned有3種不同含義符號(hào)位擴(kuò)展lb:擴(kuò)展lbu:無(wú)擴(kuò)展溢出add,addi,sub,mult,div:檢測(cè)addu,addiu,subu,multu,divu:不檢測(cè)符號(hào)數(shù)slt,slti:符號(hào)數(shù)sltu,sltiu:無(wú)符號(hào)數(shù)83小測(cè)試根據(jù)匯編程序,請(qǐng)選擇正確的C語(yǔ)句填入C代碼的空白處do{i--;}while(_________);Loop:

#i$s0,j$s1addi$s0,$s0,-1#i=i-1

slti$t0,$s1,2#$t0=(j<2)

beq$t0,$0,Loop

#gotoLoopif$t0==0slt$t0,$s1,$s0#$t0=(j<i)

bne$t0,$0,Loop

#gotoLoopif$t0!=0j≥2||j<i?j≥2&&j<i?j<2||j≥i?j<2&&j≥i?目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序偽指令指令編碼匯編與反匯編實(shí)戰(zhàn)偽指令很多C語(yǔ)句對(duì)應(yīng)到MIPS指令時(shí)很不直觀例如:C的賦值語(yǔ)句a=b,會(huì)用某條運(yùn)算指令實(shí)現(xiàn),如addiMIPS定義了一組

偽指令,從而使得程序更可讀更易編寫偽指令不是真正的指令偽指令只是增加了可讀性偽指令要被轉(zhuǎn)換為實(shí)際指令示例

movedst,src

轉(zhuǎn)換為

addidst,src,086pseudo-instruction~偽指令常用偽指令Movemovedst,src把src賦值給dstLoadAddress(la)ladst,label加載特定標(biāo)號(hào)對(duì)應(yīng)的地址至dstLoadImmediate(li)lidst,imm加載一個(gè)32位立即數(shù)至dst87匯編寄存器問(wèn)題匯編器把一條偽指令轉(zhuǎn)換為真實(shí)指令時(shí),可能需要多條真實(shí)指令這組真實(shí)指令之間就必須通過(guò)某個(gè)寄存器來(lái)傳遞信息如果任意使用某個(gè)寄存器,則存在這個(gè)寄存器被匯編器誤寫的可能解決方案保留$1($at)作為匯編器專用寄存器由于匯編器會(huì)使用這個(gè)寄存器,因此從代碼安全角度,其他代碼不應(yīng)再使用這個(gè)寄存器88

編號(hào)名稱用途0$zero常量012-34-78-15$t0-$t7臨時(shí)變量16-23$s0-$s7程序變量24-25$t8-$t9臨時(shí)變量28293031$at匯編器保留MALvs.TALTrueAssemblyLanguage(TAL)真實(shí)指令,是計(jì)算機(jī)能夠理解和執(zhí)行的MIPSAssemblyLanguage(MAL)提供給匯編程序員使用的指令(包含偽指令)每條MAL指令對(duì)應(yīng)1條或多條TAL指令主要是針對(duì)偽指令TAL?MAL89目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序移位運(yùn)算指令編碼匯編與反匯編實(shí)戰(zhàn)移位指令1/3C語(yǔ)言有移位操作,MIPS也定義了多條移位指令移位指令可以從3個(gè)維度來(lái)分析方向:左移還是向右移性質(zhì):邏輯移位還是算術(shù)移位對(duì)于向左移位來(lái)說(shuō),低位永遠(yuǎn)是補(bǔ)0只有向右移位,才存在高位是補(bǔ)0還是符號(hào)位的選擇問(wèn)題。如果補(bǔ)0,那就是邏輯移位,如果是補(bǔ)符號(hào)位,則為算術(shù)移位。移位量:對(duì)于32位寄存器,移動(dòng)位數(shù)的合理最大取值為31,即0x1F如何在指令中表示這個(gè)移位量呢?方式1:由一個(gè)5位的立即數(shù)來(lái)表示移位量方式2:用某寄存器的值來(lái)表示移位量。如果用寄存器來(lái)表示移位量,則只有該寄存器的最低5位被CPU識(shí)別為移位量,而高27位無(wú)論取何值均無(wú)意義。91問(wèn)題根據(jù)上述3個(gè)維度,應(yīng)該定義幾條指令?移位指令2/3MIPS共6條移位指令如果使用立即數(shù):只有0~31有效如果使用寄存器:寄存器的低5位有效(按5位無(wú)符號(hào)數(shù)對(duì)待)92指令功能示例sll邏輯左移sll$t0,$s0,16srl邏輯右移srl$t0,$s0,16sra算術(shù)右移sra$t0,$s0,16sllv邏輯可變左移sllv$t0,$s0,$s1srlv邏輯可變右移srlv$t0,$s0,$s1srav算術(shù)可變右移srav$t0,$s0,$s1移位指令3/3示例93addi$t0,$0,-256#$t0=0xFFFFFF00sll$s0,$t0,3#$s0=0xFFFFF800srl$s1,$t0,8#$s1=0x00FFFFFFsra$s2,$t0,8#$s2=0xFFFFFFFFaddi$t1,$0,-22#$t1=0xFFFFFFEA#low5:0b01010sllv$s3,$t0,$t1#$s3=0xFFFC0000目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序寄存器加載立即數(shù)高位指令編碼匯編與反匯編實(shí)戰(zhàn)如何計(jì)算32位立即數(shù)?32位立即數(shù)的應(yīng)用場(chǎng)景,如:addi/slti/andi/ori:等需要計(jì)算2個(gè)32位數(shù)lw/sw:在使用前,需要先設(shè)置基地址寄存器的值(32位)解決方案:不改變指令格式,而是增加一條新指令LoadUpperImmediate(lui)luireg,immreg的高16位寫入imm,低16位寫入0RTL:R[reg]imm||01695lui示例需求:addi$t0,$t0,0xABABCDCD這是一條偽指令!會(huì)被assembler轉(zhuǎn)換為3條指令

lui$at,0xABAB#高16位

ori$at,$at,0xCDCD#低16位

add$t0,$t0,$at#賦值通過(guò)增加lui,MIPS可以用16位立即數(shù)來(lái)處理任意大小的數(shù)據(jù)96T手工編寫匯編時(shí),盡量不適$at;只應(yīng)由assembler使用$at

目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序函數(shù)指令編碼匯編與反匯編實(shí)戰(zhàn)實(shí)現(xiàn)函數(shù)的6個(gè)步驟1、調(diào)用者把參數(shù)放置在某個(gè)地方以便函數(shù)能訪問(wèn)2、調(diào)用者轉(zhuǎn)移控制給被調(diào)用的函數(shù)3、函數(shù)獲取局部變量對(duì)應(yīng)的空間4、函數(shù)執(zhí)行具體功能5、函數(shù)把返回值放置在某個(gè)地方,然后恢復(fù)使用的資源6、返回控制給調(diào)用者98函數(shù)相關(guān)寄存器由于寄存器比主存快,因此盡可能的用寄存器$a0–$a3:4個(gè)傳遞參數(shù)的寄存器$v0–$v1:2個(gè)傳遞返回值的寄存器$ra:返回地址寄存器,保存著調(diào)用者的地址99編號(hào)名稱用途0$zero常量01$at匯編器保留2-34-78-15$t0-$t7臨時(shí)變量16-23$s0-$s7程序變量24-25$t8-$t9臨時(shí)變量28293031$a0-$a3參數(shù)$v0-$v1返回值$ra返回地址函數(shù)調(diào)用指令JumpandLink

(jal)jallabel把jal的下一條指令的地址保存在$ra,然后跳轉(zhuǎn)到label(即函數(shù)地址)jal的用途是調(diào)用函數(shù)JumpRegister(jr)jrsrc無(wú)條件跳轉(zhuǎn)到保存在src的地址(通常就是$ra)jr的用途是從函數(shù)返回100PCPC(programcounter)是一個(gè)特殊寄存器,用于保存當(dāng)前正在指令的指令的地址PC是馮式體系結(jié)構(gòu)計(jì)算機(jī)的關(guān)鍵環(huán)節(jié)在MIPS中,PC對(duì)于程序員不可見(jiàn),但可以被jal訪問(wèn)注意:保存在$ra的是PC+4,而不是PC否則當(dāng)函數(shù)返回的時(shí)候,就會(huì)再次返回到j(luò)al本身了101函數(shù)調(diào)用示例102...sum(a,b);.../*a

$s0,b

$s1*/

intsum(intx,inty){

returnx+y;

}

1000addi$a0,$s0,0#x=a1004addi$a1,$s1,0#y=b1008jalsum#$ra=1012,gotosum1012...2000sum:add$v0,$a0,$a12004jr$ra

#return地址CMIPS實(shí)現(xiàn)函數(shù)的6個(gè)步驟1、調(diào)用者把參數(shù)放置在某個(gè)地方以便函數(shù)能訪問(wèn)$a0~$a32、調(diào)用者轉(zhuǎn)移控制給被調(diào)用的函數(shù)jal3、函數(shù)獲取局部變量對(duì)應(yīng)的空間??4、函數(shù)執(zhí)行具體功能5、函數(shù)把返回值放置在某個(gè)地方,然后恢復(fù)使用的資源$v0~$v16、返回控制給調(diào)用者103保存和恢復(fù)寄存器Q:為什么需要保存寄存器?理由1:寄存器數(shù)量太少,不可能只用寄存器就能編寫實(shí)用程序理由2:如果被調(diào)用函數(shù)繼續(xù)調(diào)用函數(shù),會(huì)發(fā)生什么? ($ra

被覆蓋了!)Q:寄存器保存在什么地方?棧!$sp:棧指針寄存器。指針指向棧底104編號(hào)名稱用途0$zero常量01$at匯編器保留2-3$v0~$v1返回值4-7$a0~$a4參數(shù)8-15$t0-$t7臨時(shí)變量16-23$s0-$s7程序變量24-25$t8-$t9臨時(shí)變量28293031$ra返回地址$sp棧指針stack~棧主存分配的基本方案棧幀:函數(shù)為獲得保存寄存器而將$sp向0方向調(diào)整的空間棧幀容量=要保存的寄存器數(shù)量X4105∞0地址$sp堆靜態(tài)數(shù)據(jù)代碼自由空間棧棧增長(zhǎng)方向堆增長(zhǎng)方向主存已保存在棧中的數(shù)據(jù)動(dòng)態(tài)分配空間全局變量、靜態(tài)變量、字符串常量指令stackframe/棧幀函數(shù)示例intsumSquare(intx,inty){returnmult(x,x)+y;}都需要保存哪些寄存器?1)$ra:由于sumSquare要調(diào)用mult,因此$ra會(huì)被覆蓋2)$a1:給sumSquare傳遞y,但還給mult傳遞x關(guān)鍵是在sumSquare中,會(huì)先傳遞x然后才引用y,因此y就被x覆蓋了為了保存這2個(gè)寄存器,首先需要將$sp

向下移動(dòng)8個(gè)字節(jié)棧幀容量為8字節(jié):要保存2個(gè)寄存器,共需要8個(gè)字節(jié)106函數(shù)示例intsumSquare(intx,inty){returnmult(x,x)+y;}sumSquare:

addi$sp,$sp,-8#makespaceonstacksw$ra,4($sp)#saveretaddr

sw$a1,0($sp)#savey

move

$a1,$a0#set2ndmultargjalmult

#callmult

lw$a1,0($sp)#restorey

add$v0,$v0,$a1

#retval=mult(x,x)+y

lw$ra,4($sp)#restoreretaddr

addi$sp,$sp,8#restorestack

jr$ramult:...107pushpop函數(shù)的架構(gòu)framesize

=要保存的寄存器個(gè)數(shù)x4108func_label:

addi$sp,$sp,-framesize

sw$ra,[framesize-4]($sp)

saveotherregsifneedbe

...

restoreotherregsifneedbe

lw$ra,[framesize-4]($sp)addi$sp,$sp,framesize

jr$raEpiloguePrologueBody(可以調(diào)用其他函數(shù)…)rastack局部變量和數(shù)組由于寄存器只有32個(gè),因此編譯器絕大多數(shù)情況下不可能把函數(shù)需要的所有局部變量都分配在寄存器局部變量存放在函數(shù)自己的棧幀中這樣當(dāng)函數(shù)返回時(shí),隨著$sp的回調(diào),局部變量自然就被釋放了其他局部變量,如數(shù)組、結(jié)構(gòu)等,同樣也是存儲(chǔ)在棧幀中為局部變量分配空間的方法是與保存寄存器是完全相同將$sp向下調(diào)整,產(chǎn)生的空間用于存儲(chǔ)局部變量109局部變量和數(shù)組由于寄存器只有32個(gè),因此編譯器絕大多數(shù)情況下不可能把函數(shù)需要的所有局部變量都分配在寄存器110高位地址內(nèi)存單元

內(nèi)存單元

內(nèi)存單元

內(nèi)存單元內(nèi)存單元

?

$sp?

???

$sp

$s0~$s7

$s0~$s7

$s0~$s7

$ra$ra

$ra局部變量

$sp局部變量局部變量

$sp

$v0~$v1

$a0~$a3

$t0~$t9

額外的參數(shù)

$sp

...

...

...

低位地址

動(dòng)作保存程序變量寄存器(含預(yù)留局部變量空間)保存臨時(shí)變量寄存器恢復(fù)臨時(shí)變量寄存器恢復(fù)程序變量寄存器(含丟棄局部變量空間)時(shí)機(jī)剛進(jìn)入函數(shù)時(shí)調(diào)用其他函數(shù)前調(diào)用其他函數(shù)后執(zhí)行jr返回前序號(hào)0)1)2)3)4)寄存器的保護(hù)分析$s0~$s7:程序員變量分析:所有函數(shù)都要使用程序員變量程序員變量的生命周期與函數(shù)生命周期相同,即進(jìn)入函數(shù)就有效,退出函數(shù)后無(wú)效保護(hù)前提:用哪些,保護(hù)哪些保護(hù)動(dòng)作:剛進(jìn)入函數(shù)時(shí)保存;退出函數(shù)前恢復(fù)$ra:函數(shù)返回地址保護(hù)前提:如果繼續(xù)調(diào)用子函數(shù),那么就必須保護(hù)否則函數(shù)就不能返回至父函數(shù)保護(hù)動(dòng)作:剛進(jìn)入函數(shù)時(shí)保存;退出函數(shù)前恢復(fù)111父函數(shù)函數(shù)子函數(shù)

寄存器的保護(hù)分析$t0~$t9:臨時(shí)變量(前提:MIPS約定其服務(wù)于表達(dá)式計(jì)算)無(wú)需保護(hù):表達(dá)式中不調(diào)用子函數(shù),故不存在被子函數(shù)修改的可能需要保護(hù):表達(dá)式中調(diào)用子函數(shù),故存在被子函數(shù)修改的可能保護(hù)前提:如果其值在子函數(shù)調(diào)用前后必須保持一致保護(hù)動(dòng)作:調(diào)用子函數(shù)前保存;在調(diào)用子函數(shù)后恢復(fù)112e=a+b+c+d;//$t0=a+b,$t1=c+df1();z=x+y+f2();//$t0=x+y//$t0有可能被f2()修改寄存器的保護(hù)分析$a0~$a3,$v0~$v1:參數(shù),返回值$a0~$a3:傳遞給了子函數(shù),故子函數(shù)可自由使用$v0~$v1:因?yàn)樽雍瘮?shù)會(huì)設(shè)置返回值,故子函數(shù)可自由使用保護(hù)前提:如果其值在調(diào)用子函數(shù)前后必須保持一致,則:保護(hù)動(dòng)作:調(diào)用子函數(shù)前保存;在調(diào)用子函數(shù)后恢復(fù)$at:匯編器使用,故無(wú)需保護(hù)$k0~$k1:操作系統(tǒng)使用(現(xiàn)階段可以不使用)$sp:棧切換時(shí)才需要保護(hù)(現(xiàn)階段可以不使用)棧切換:通常屬于操作系統(tǒng)范疇$fp、$gp:在生成復(fù)雜的存儲(chǔ)布局時(shí)使用(屬于編譯范疇)113寄存器的保護(hù)分析序號(hào)名稱MIPS匯編約定的用途分類保護(hù)的前提條件何時(shí)保護(hù)與恢復(fù)16~23$s0~$s7程序員變量強(qiáng)保護(hù)如果需要使用進(jìn)入函數(shù)時(shí)保存退出函數(shù)前恢復(fù)31$ra函數(shù)返回地址如果調(diào)用子函數(shù)2~3$v0~$v1函數(shù)返回值弱保護(hù)如果要求其值在調(diào)用子函數(shù)前后必須保持一致調(diào)用子函數(shù)前保存子函數(shù)返回后恢復(fù)4~7$a0~$a3函數(shù)參數(shù)8~15,24~25$t0~$t9臨時(shí)變量114SavedRegister:$s0~$s7,$ra英文:preservedregister;中文:保護(hù)寄存器,保存寄存器VolatileRegister:$t0~$t9,$a0~$a3,$v0~$v1英文:non-preservedregister;中文:非保護(hù)寄存器,非保存寄存器強(qiáng)保護(hù)寄存器的保護(hù)機(jī)制代碼框架進(jìn)入函數(shù)后,立刻調(diào)整棧并保存;在函數(shù)返回時(shí)才恢復(fù)115123456789101112131415161718函數(shù)_lable:addiu$sp,$sp,-framesizesw$ra,[framesize-4]($sp)sw$s0,[framesize-8]($sp)sw$s1,[framesize-12]($sp)#…sw$s7,0($sp)

#使用$s0~$s7#調(diào)用其他子函數(shù)

lw$s7,0($sp)#…lw$s1,[framesize-12]($sp)lw$s0,[framesize-8]($sp)lw$ra,[framesize-4]($sp)addiu$sp,$sp,framesizejr$ra

分配棧幀保存$ra保存$s0~$s7中后續(xù)要使用的寄存器

恢復(fù)函數(shù)保護(hù)的寄存器

回收棧幀

弱保護(hù)寄存器的保護(hù)機(jī)制代碼框架在調(diào)用其他子函數(shù)時(shí)才調(diào)整棧并保存;在子函數(shù)返回時(shí)立即恢復(fù)有N次子函數(shù)調(diào)用,就可能N次保護(hù)與恢復(fù);不調(diào)用子函數(shù),就無(wú)需保護(hù)116123456789101112131415161718函數(shù)_lable:#其他函數(shù)代碼

addiu$sp,$sp,-tmpsizesw$t[i],[tmpsize-4]($sp)sw$t[i+1],[tmpsize-8]($sp)#其他需保存的寄存器sw$t7,0($sp)

jal子函數(shù)

lw$t7,0($sp)#…lw$t[i+1],[tmpsize-8]($sp)lw$t[i],[tmpsize-4]($sp)addiu$sp,$sp,tmpsize

#其他函數(shù)代碼

在調(diào)用子函數(shù)前分配棧幀保存寄存器

調(diào)用子函數(shù)

恢復(fù)寄存器

回收棧幀

小測(cè)試下列哪個(gè)陳述是錯(cuò)誤的?117jal保存PC+1到$ra函數(shù)如果不擔(dān)心$ti值在調(diào)用子函數(shù)后發(fā)生改變,則無(wú)需保存和恢復(fù)它們函數(shù)如果要使用($si),就必須保存和恢復(fù)它們MIPS使用jal指令來(lái)調(diào)用函數(shù),并使用jr指令函數(shù)返回????小結(jié):函數(shù)調(diào)用通過(guò)組合beq與slt

指令,可以實(shí)現(xiàn)各種比較判斷偽指令使得代碼更易讀函數(shù)機(jī)制用jal實(shí)現(xiàn)函數(shù)調(diào)用,用jr實(shí)現(xiàn)函數(shù)返回用$a0-$a3傳遞參數(shù),用$v0-$v1傳遞返回值寄存器保護(hù)從用途看,寄存器可以分為強(qiáng)保護(hù)和弱保護(hù)兩大類強(qiáng)保護(hù)寄存器:一進(jìn)函數(shù)就保護(hù),退出時(shí)恢復(fù)弱保護(hù)寄存器:調(diào)用子函數(shù)時(shí)保護(hù),子函數(shù)一返回就恢復(fù)棧用于保存寄存器、局部變量等118目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序空操作指令編碼匯編與反匯編實(shí)戰(zhàn)空操作空操作(NOP)是一條特殊指令CPU執(zhí)行該指令時(shí),不會(huì)產(chǎn)生任何實(shí)質(zhì)性動(dòng)作出于同步等目的,有時(shí)需在程序中插入NOP在本書里,NOP主要用于解決流水線沖突在MIPS中,NOP指令是不存在當(dāng)匯編器發(fā)現(xiàn)NOP時(shí),會(huì)將其轉(zhuǎn)換為sll$0,$0,0CPU執(zhí)行這條指令時(shí),只會(huì)解析指令語(yǔ)義,但不會(huì)產(chǎn)生任何實(shí)質(zhì)操作1)$0值恒為0:故任何移位均無(wú)意義2)移位數(shù)為0:故不會(huì)產(chǎn)生移位操作3)$0不可寫:故寫入操作不會(huì)發(fā)生120NOP:NoOperationPerformed目錄程序執(zhí)行的基本原理指令格式及其操作數(shù)指令集與匯編程序指令編碼存儲(chǔ)型程序概念匯編與反匯編實(shí)戰(zhàn)程序存儲(chǔ)概念指令以二進(jìn)制方式被編碼程序存儲(chǔ)在存儲(chǔ)器中;可以從存儲(chǔ)器中讀取程序也可以寫入程序存儲(chǔ)方式與數(shù)據(jù)存儲(chǔ)完全相同簡(jiǎn)化了計(jì)算機(jī)系統(tǒng)的軟件/硬件設(shè)計(jì)存儲(chǔ)器技術(shù)既可以存儲(chǔ)數(shù)據(jù),也可以存儲(chǔ)程序由于存儲(chǔ)在存儲(chǔ)器單元中,因此指令和數(shù)據(jù)都有地址122二進(jìn)制兼容程序是以二進(jìn)制形式發(fā)布的指令集與程序之間是強(qiáng)相關(guān)新機(jī)器不僅能運(yùn)行基于新指令編譯產(chǎn)生的新程序,同樣也最好能運(yùn)行老程序上述特性被稱為向后兼容(backwardcompatible)示例:今天的i7處理器仍然能運(yùn)行1981年在8086處理器上編譯產(chǎn)生的程序123把指令當(dāng)做數(shù)看待1/2假設(shè):所有的數(shù)據(jù)都是以字為單位的(32位)每個(gè)寄存器是字寬度的lw和sw讀寫主存的單位是字問(wèn)題:如何用二進(jìn)制表示指令?計(jì)算機(jī)只能理解0和1,無(wú)法理解“add$t0,$0,$0”回答:數(shù)據(jù)以字為單位,每條指令同樣被編碼為一個(gè)字!MIPS的所有指令的二進(jìn)制編碼寬度均為32位124把指令當(dāng)做數(shù)看待2/2指令的32位被劃分為若干域域:占據(jù)若干特定位;代表特定含

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論