計(jì)算機(jī)系統(tǒng)-從應(yīng)用程序到底層實(shí)現(xiàn) 課件 第10講-程序的機(jī)器級(jí)表示:控制_第1頁(yè)
計(jì)算機(jī)系統(tǒng)-從應(yīng)用程序到底層實(shí)現(xiàn) 課件 第10講-程序的機(jī)器級(jí)表示:控制_第2頁(yè)
計(jì)算機(jī)系統(tǒng)-從應(yīng)用程序到底層實(shí)現(xiàn) 課件 第10講-程序的機(jī)器級(jí)表示:控制_第3頁(yè)
計(jì)算機(jī)系統(tǒng)-從應(yīng)用程序到底層實(shí)現(xiàn) 課件 第10講-程序的機(jī)器級(jí)表示:控制_第4頁(yè)
計(jì)算機(jī)系統(tǒng)-從應(yīng)用程序到底層實(shí)現(xiàn) 課件 第10講-程序的機(jī)器級(jí)表示:控制_第5頁(yè)
已閱讀5頁(yè),還剩42頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

《計(jì)算機(jī)系統(tǒng)》程序的控制《計(jì)算機(jī)系統(tǒng)》課程教學(xué)組2025年春季學(xué)期控制的重要性控制現(xiàn)代漢語(yǔ)詞典釋義:掌握、操縱、占有。語(yǔ)出《魏書(shū)·太祖道武帝紀(jì)》:“昔朕遠(yuǎn)祖,總御幽都,控制遐國(guó)。”《新唐書(shū)》亦云:“勁兵重地,控制萬(wàn)里?!背绦虻目刂疲阂罁?jù)算法設(shè)定的邏輯,決定程序執(zhí)行過(guò)程中數(shù)據(jù)的流向和指令執(zhí)行的順序。理論和實(shí)踐證明,無(wú)論多復(fù)雜的算法均可通過(guò)順序、選擇、循環(huán)3種基本控制結(jié)構(gòu)構(gòu)造出來(lái)。程序控制直接決定了程序的正確運(yùn)行和運(yùn)算結(jié)果的正確獲得。程序控制與體系機(jī)器底層的程序控制方式與計(jì)算機(jī)體系密切相關(guān)Win-tel架構(gòu)和生態(tài)統(tǒng)治了全球大部分市場(chǎng)。ARM架構(gòu)作為開(kāi)源架構(gòu)被很多國(guó)產(chǎn)系統(tǒng)借鑒和使用。iOS自成體系,且非常封閉。Android系統(tǒng)號(hào)稱(chēng)開(kāi)源,但華為同樣遭到Google打壓封鎖。飛天(阿里)、麒麟(Ubuntu)、鴻蒙(華為)等國(guó)產(chǎn)體系正迎頭趕上。程序控制的意義程序控制結(jié)構(gòu)組成了程序的主體:順序結(jié)構(gòu)、選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu)確保程序的運(yùn)行按照算法邏輯的設(shè)定進(jìn)行提供了程序調(diào)試的關(guān)鍵節(jié)點(diǎn),便于觀察重要數(shù)據(jù)的流向思考:大學(xué)生活就是基于人生規(guī)劃執(zhí)行的一段程序,大學(xué)生應(yīng)當(dāng)編寫(xiě)好自己的“程序控制”代碼,確保大學(xué)學(xué)業(yè)的順利完成??刂疲簵l件碼條件分支循環(huán)內(nèi)容提要01020304switch語(yǔ)句處理器狀態(tài)當(dāng)前運(yùn)行程序的相關(guān)信息臨時(shí)數(shù)據(jù)

(%eax,…)運(yùn)行棧幀的地址

(%ebp,%esp

)即將要執(zhí)行的指令地址

(%eip,…)標(biāo)志位

(CF,ZF,SF,OF)%eip通用寄存器當(dāng)前棧指針當(dāng)前棧幀指令指針CFZFSFOF%eax%ecx%edx%ebx%esi%edi%esp%ebp條件碼每個(gè)條件碼占一個(gè)bitCF最高位產(chǎn)生了進(jìn)位,無(wú)符號(hào)操作數(shù)的溢出SF

符號(hào)標(biāo)志,操作結(jié)果為負(fù)數(shù)ZF

零標(biāo)志OF

溢出標(biāo)志(有符號(hào)數(shù)signed)例如:addl/addqSrc,Dest?t=a+bCFset

,如果t溢出ZFset

,如果

t==0SFset

,如果

t<0(assigned)OFset,如果有符號(hào)數(shù)溢出lea/mov

指令不設(shè)置條件碼條件碼寄存器CMPcmplSrc,Dest;Dest–Src,影響標(biāo)志位cmplb,a

等價(jià)于計(jì)算

a-b,但不改變a與b的值。CFset 無(wú)符號(hào)數(shù)運(yùn)算時(shí)有進(jìn)位ZFset

如果

a==bSFset

如果

有符號(hào)數(shù)(a-b)<0OFset

如果有符號(hào)數(shù)運(yùn)算溢出條件碼設(shè)置TESTtestl/testqSrc,Dest;Dest&Src,影響標(biāo)志位testlb,a等價(jià)于計(jì)算a&b(但不改變a或b的值)ZF

set

如果a&b==0SF

set

如果a&b<0條件碼設(shè)置條件碼設(shè)置以四個(gè)bit的數(shù)為例,有符號(hào)數(shù)能表示-8~7(1000~0111),無(wú)符號(hào)數(shù)能表示0~15(0000~1111)6>36-3=3, SF=0, OF=0,

SF⊕OF=04>-24-(-2)=6, SF=0, OF=0-4<-2-2-(-4)=2, SF=0, OF=06<76-7=-1, SF=1, OF=0, SF⊕OF=1-4>-6-4-(-6)=2, SF=0, OF=0-4<7-4-7=-11=10101=0101(正), SF=0, OF=1, SF⊕OF=17>-57-(-5)=12=01100=1100(負(fù)), SF=1, OF=1, SF⊕OF=0當(dāng)出現(xiàn):正+正=負(fù)、負(fù)+負(fù)=正、正-負(fù)=負(fù)、負(fù)-正=正

的情況,就是產(chǎn)生了溢出,OF=1條件碼設(shè)置SetX指令:根據(jù)條件碼的組合將一個(gè)字節(jié)設(shè)置為0或1SetXConditionDescriptionsete/setzZFEqual/Zerosetne/setnz~ZFNotEqual/NotZerosetsSFNegativesetns~SFNonnegativesetg~(SF^OF)&~ZFGreater(Signed)setge~(SF^OF)GreaterorEqual(Signed)setl(SF^OF)Less(Signed)setle(SF^OF)|ZFLessorEqual(Signed)seta~CF&~ZFAbove(unsigned)setbCFBelow(unsigned)有符號(hào)數(shù)無(wú)符號(hào)數(shù)設(shè)置條件碼movl12(%ebp),%eax #eax=ycmpl%eax,8(%ebp) #Comparex:ysetg%al #al=x>ymovzbl%al,%eax #Zerorestof%eaxintgt(intx,inty){returnx>y;}Body%eax%ah%al課堂習(xí)題leal $8(%edx,%eax,2),%eaxleal (,%edx,4),%edxcmpl %edx,%eaxsetg %cl%eax0x08%ecx0x00%edx0x06%eax=0x1d,%edx=0x16,%cl=0x00%eax=0x1e,%edx=0x18,%cl=0x00%eax=0x30,%edx=0x24,%cl=0x01%eax=0x1e,%edx=0x18,%cl=0x01控制:條件碼條件分支循環(huán)內(nèi)容提要01020304switch語(yǔ)句跳轉(zhuǎn)指令jX指令:根據(jù)不同的條件跳轉(zhuǎn)到某條指令處執(zhí)行jXConditionDescriptionjmp1無(wú)條件跳轉(zhuǎn)je/jzZFEqual/ZeroJne/jnz~ZFNotEqual/NotZerojsSFNegativejns~SFNonnegativejg~(SF^OF)&~ZFGreater(Signed)jge~(SF^OF)GreaterorEqual(Signed)jl(SF^OF)Less(Signed)jle(SF^OF)|ZFLessorEqual(Signed)ja~CF&~ZFAbove(unsigned)jbCFBelow(unsigned)有符號(hào)數(shù)無(wú)符號(hào)數(shù)條件跳轉(zhuǎn)intabsdiff(intx,inty){intresult;if(x>y){result=x-y;}else{result=y-x;}returnresult;}absdiff:pushl%ebpmovl%esp,%ebpmovl8(%ebp),%edxmovl12(%ebp),%eaxcmpl%eax,%edxjle.L6subl%eax,%edxmovl%edx,%eaxjmp.L7.L6:subl%edx,%eax.L7:popl%ebpretBody1SetupFinishBody2bBody2a%edx=x%eax=y條件跳轉(zhuǎn)條件跳轉(zhuǎn)absdiff:pushl%ebpmovl%esp,%ebpmovl8(%ebp),%edxmovl12(%ebp),%eaxcmpl%eax,%edxjle.L6subl%eax,%edxmovl%edx,%eaxjmp

.L7.L6:subl%edx,%eax.L7:popl%ebpretBody1SetupFinishBody2bBody2aintgoto_ad(intx,inty){intresult;if(x<=y)gotoElse;result=x-y;gotoExit;Else:result=y-x;Exit:returnresult;}C中可以采用goto語(yǔ)句進(jìn)行跳轉(zhuǎn),與機(jī)器級(jí)的語(yǔ)言風(fēng)格類(lèi)似但通常被認(rèn)為是一種比較“l(fā)ow”的編程風(fēng)格%edx=x%eax=y分支跳轉(zhuǎn)CCodeval=Test?Then_Expr:Else_Expr;GotoVersionnt=!Test; if(nt)gotoElse;val=Then_Expr;

gotoDone;Else:val=Else_Expr;Done: ...Test是一個(gè)返回整數(shù)值的表達(dá)式=0邏輯假≠0邏輯真為每一個(gè)分支都產(chǎn)生一段代碼根據(jù)條件執(zhí)行合適的代碼段val=x>y?x-y:y-x;等價(jià)條件傳送條件傳送指令——滿足條件才傳送Instructionsupports:if(Test)DestSrc先計(jì)算一個(gè)條件操作的兩種結(jié)果,然后根據(jù)條件選擇某一個(gè)優(yōu)勢(shì):能夠更好的匹配現(xiàn)代處理器的特性流水線分支預(yù)測(cè)CCodetval=Then_Expr;result=Else_Expr;t=Test;if(t)result=tval;returnresult;條件傳送intcomvdiff(intx,inty){inttval=y-x;intrval=x-y;inttest=x<y;if(test)rval=tval;resultrval;}comvdiff:movl8(%ebp),%ecxmovl12(%ebp),%edxmovl%edx,%ebxsubl%ecx,%ebxmovl%ecx,%eaxsubl%edx,%eaxcmpl%edx,%ecxcmovle%ebx,%eaxabsdiff:pushl%ebpmovl%esp,%ebpmovl8(%ebp),%edxmovl12(%ebp),%eaxcmpl%eax,%edxjle.L6subl%eax,%edxmovl%edx,%eaxjmp.L7.L6:subl%edx,%eax.L7:popl%ebpretCCode條件傳送條件跳轉(zhuǎn)避免了跳轉(zhuǎn)指令CPU無(wú)需做分支預(yù)測(cè),避免預(yù)測(cè)錯(cuò)誤的代價(jià)流水線效率更高條件傳送C代碼非優(yōu)化編譯:gcc-Stest.c:匯編代碼出現(xiàn)了jle這樣的跳轉(zhuǎn)指令。對(duì)于使用了流水線的CPU,這樣的跳轉(zhuǎn)是存在隱患的(P140),分支預(yù)測(cè)失敗就會(huì)刷新掉所有流水線中取到而未執(zhí)行的指令,影響運(yùn)行性能。優(yōu)化:gcc-S-O1test.c經(jīng)過(guò)優(yōu)化后的代碼沒(méi)有了跳轉(zhuǎn)指令,取而代之的是一個(gè)條件傳送指令——cmovle。使得控制流不依賴(lài)于數(shù)據(jù),流水線也更容易保持滿狀態(tài)。計(jì)算代價(jià)非法操作副作用兩個(gè)計(jì)算過(guò)程都需要運(yùn)行一般來(lái)說(shuō),只有兩個(gè)計(jì)算過(guò)程都比較簡(jiǎn)單的時(shí)候,才能夠發(fā)揮優(yōu)勢(shì)在p為0的時(shí)候,仍然會(huì)去引用*p,從而產(chǎn)生非法操作兩個(gè)表達(dá)式都進(jìn)行了計(jì)算產(chǎn)生了意料之外的賦值過(guò)程條件傳送val=Test(x)?Hard1(x):Hard2(x);val=p?*p:0;val=x>0?x*=7:x+=3;課堂思考使用條件傳送時(shí)要如何避免出現(xiàn)錯(cuò)誤?如何提高效率?控制:條件碼條件分支循環(huán)內(nèi)容提要01020304switch語(yǔ)句do-while循環(huán)CCodeintpcount_do(unsignedx){intresult=0;

do{result+=x&0x1;x>>=1;}while(x);returnresult;}計(jì)算x中有多少個(gè)1(“popcount”)

使用條件跳轉(zhuǎn)指令來(lái)進(jìn)行條件判斷movl

$0,%ecx #result=0.L2: #loop:movl %edx,%eaxandl $1,%eax #t=x&1addl %eax,%ecx #result+=tshrl %edx #x>>=1jne .L2 #If!0,gotoloop寄存器%edxx%ecxresultwhile循環(huán)CCodeforwhileloopCcodefordoloopWhile和do-while二者的代碼是否完全一致?都是條件測(cè)試失敗退出循環(huán)do-while循環(huán)至少執(zhí)行一次循環(huán)體intpcount_while(unsignedx){intresult=0;

while(x){result+=x&0x1;x>>=1;}returnresult;}intpcount_do(unsignedx){intresult=0;do{result+=x&0x1;x>>=1;}

while(x)returnresult;}for循環(huán)CCode#defineWSIZE8*sizeof(int)intpcount_for(unsignedx){inti;intresult=0;

for(i=0;i<WSIZE;i++){unsignedmask=1<<i;result+=(x&mask)!=0;}returnresult;}各循環(huán)對(duì)比f(wàn)or(Init;Test;Update)BodyForVersionInit;while(Test){BodyUpdate;}WhileVersionInit;if(!Test)gotodone;doBodyUpdatewhile(Test);done:Init;if(!Test)gotodone;loop:BodyUpdateif(Test)gotoloop;done:HunanUniversityDo-whileVersionGotoVersion控制:條件碼條件分支循環(huán)內(nèi)容提要01020304switch語(yǔ)句switch語(yǔ)句多重分支使用跳轉(zhuǎn)表x=2時(shí)無(wú)breaklongswitch_eg(longx,longy,longz){longw=1;switch(x){case1:w=y*z;break;case2:w=y/z;/*FallThrough*/case3:w+=z;break;case5:case6:w-=z;break;default:w=2;}returnw;}跳轉(zhuǎn)表CodeBlock0Targ_0:CodeBlock1Targ_1:CodeBlock2Targ_2:CodeBlockn–1Targ_n-1:???target=JTab[x];goto*target;switch(x){caseval_0:Block0caseval_1:Block1?

?

?caseval_n-1:Blockn–1}SwitchFormApproximateTranslationTarg_0Targ_1Targ_2Targ_n-1???jtab:JumpTableJumpTargetsswitch語(yǔ)句setup:longswitch_eg(longx,longy,longz){longw=1;switch(x){...}returnw;}switch_eg:pushl %ebp #Setupmovl %esp,%ebp #Setupmovl 8(%ebp),%eax #%eax=xcmpl $6,%eax #Comparex:6ja .L8 #Ifunsigned‘>’gotodefaultjmp *.L4(,%eax,4) #Goto*JTab[x]注意:此處W沒(méi)有進(jìn)行初始化Targ0Targ1Targ2Targn-1???jtab:JumpTableJumptable.section .rodata .align4.L4: .long .L8 #x=0 .long .L3 #x=1 .long .L5 #x=2 .long .L9 #x=3 .long .L8 #x=4 .long .L7 #x=5 .long .L7 #x=6跳轉(zhuǎn)表結(jié)構(gòu)每個(gè)跳轉(zhuǎn)地址需要4字節(jié)基址在

.L4跳轉(zhuǎn)Direct:jmp.L2直接跳轉(zhuǎn),地址為.L2Indirect:jmp*.L4(,%eax,4)跳轉(zhuǎn)表基地址:.L44是因?yàn)槊總€(gè)地址占4個(gè)字節(jié)取到有效地址.L4+eax*40≤x≤6JumpTable.section .rodata .align4.L4: .long .L8 #x=0 .long .L3 #x=1 .long .L5 #x=2 .long .L9 #x=3 .long .L8 #x=4 .long .L7 #x=5 .long .L7 #x=6跳轉(zhuǎn)表JumpTable.section .rodata .align4.L4: .long .L8 #x=0 .long .L3 #x=1 .long .L5 #x=2 .long .L9 #x=3 .long .L8 #x=4 .long .L7 #x=5 .long .L7 #x=6switch(x){case1://.L3w=y*z;break;case2://.L5w=y/z;/*FallThrough*/case3://.L9w+=z;break;case5:case6://.L7w-=z;break;default://.L8w=2;}代碼塊1.L3:#x==1movl 12(%ebp),%eax#yimull 16(%ebp),%eax#w=y*zjmp .L2 #Gotodoneswitch(x){case1: //.L3w=y*z;break;...}FallThroughlongw=1;...switch(x){... case2:w=y/z;/*FallThrough*/case3:w+=z;break;...}case2:w=y/z;gotomerge;case3:w=1;merge:w+=z;代碼塊2&3.L5: #x==2movl 12(%ebp),%eax

#ycltdidivl16(%ebp) #y/zjmp.L6.L9:

#x==3movl $1,%eax

#w=1.L6:

#merge:addl 16(%ebp),%eax #+=zjmp .L2 #Gotodonelongw=1;...switch(x){...case2: //.L5w=y/z;/*FallThrough*/case3://.L9w+=z;break;...}代碼塊5&6&default.L7: #x==5,6movl $1,%eax#w=1subl 16(%ebp),%eax#w=1-zjmp.L2#gotodone.L8: #defaultmovl$2,%eax#w=2.L2: #doneswitch(x){...case5://.L7case6://.L7w-=z;break;default://.L8w=2;}代碼塊:結(jié)束returnw;.L2: #done:popl

%ebpret使用跳轉(zhuǎn)表是一種非常有效的實(shí)現(xiàn)多重分支的方法目標(biāo)代碼準(zhǔn)備階段Label.L8becomesaddress0x80484b8Label.L4becomesaddress0x804868008048480<switch_eg>:...8048489: 772d ja80484b8<switch_eg+0x38>804848b: ff248580860408 jmp*0x8048680(,%eax,4)switch_eg:...ja.L8 #Ifunsigned>gotodefaultjmp*.L4(,%eax,4) #Goto*JTab[x]AssemblyCodeDisassembledObjectCode目標(biāo)代碼:跳轉(zhuǎn)表跳轉(zhuǎn)表在反匯編代碼中無(wú)法直接看到,可以通過(guò)GDB來(lái)觀察gdbswitch(gdb)x/7xw0x8048680Examine7hexadecimalformat“words”(4-byteseach)—x/7xw0x8048680: 0x080484b8 0x08048492 0x0804849b 0x080484a40x8048690: 0x080484b8 0x080484ae 0x080484ae跳轉(zhuǎn)表解釋.section .rodata .align4.L4: .long .L8 #x=0 .long .L3 #x=1 .long .L5 #x=2 .long .L9 #x=3 .long .L8 #x=4 .long .L7 #x=5 .long .L7 #x=60x8048680: 0x080484b8 0x08048492 0x0804849b 0x080484a40x8048690: 0x080484b8 0x080484ae 0x080484aeAddressValuex0x80486800x80484b800x80486840x804849210x80486880x804849b20x804868c0x80484a430x80486900x80484b840x80486940x80484ae50x80486980x80484ae6反匯編x=1x=2x=3x=5,6default8048492:8b450c mov0xc(%ebp),%eax8048495:0faf4510 imul0x10(%ebp),%eax8048499:eb22 jmp80484bd<switch_eg+0x3d>804849b:8b450c mov0xc(%ebp),%eax804849e:99 cltd804849f:f77d10 idivl0x10(%ebp)80484a2:eb05

jmp80484a9<switch_eg+0x29>

80484a4:b801000000 mov$0x1,%e

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論