大家在學(xué)習(xí)C語(yǔ)言過(guò)程中,可能會(huì)見(jiàn)到過(guò)一些這樣的題,就是表達(dá)式短路,表達(dá)式短路主要體現(xiàn)在C語(yǔ)言中邏輯運(yùn)算符&&和||。今天將對(duì)表達(dá)式短路的做逆向分析,來(lái)深入理解它。
首先利用表達(dá)式短路,我們可以寫(xiě)一個(gè)很經(jīng)典的累加求和的函數(shù),代碼如下:
功能很簡(jiǎn)單,就是求1+2+…+99+100的數(shù)字和的一個(gè)程序,但用遞歸寫(xiě)了出來(lái),利用邏輯與運(yùn)算,左邊判斷是否遞歸到0,右邊累加求和,其中的技巧巧妙的運(yùn)用邏輯與運(yùn)算的短路特點(diǎn),實(shí)現(xiàn)累加的效果。請(qǐng)大家自行分析理解~
下面我們斷點(diǎn)反匯編,查看重點(diǎn)num && (num += Add(num-1));語(yǔ)句的匯編代碼,如下
下面詳細(xì)分析:
;比較num是否為0! 這里也就是邏輯與表達(dá)式左邊的判斷!
0040D718?????? cmp???????? dword ptr [ebp+8],0
;判斷ZF標(biāo)志位是否為1然后進(jìn)行跳轉(zhuǎn),到return處
0040D71C????? ?je????????? Add+35h (0040d735)
;繼續(xù)把num變量送入eax寄存器
0040D71E???? ??mov???????? eax,dword ptr [ebp+8]
;對(duì)num減1
0040D721?????? sub???????? eax,1
;結(jié)果作為參數(shù),壓棧準(zhǔn)備進(jìn)入遞歸調(diào)用
0040D724??? ???push??????? eax
;繼續(xù)調(diào)用Add函數(shù),地址位于0040100a處
0040D725??? ???call??????? @ILT+5(_Add) (0040100a)
;棧清空
0040D72A?? ????add???????? esp,4
;將num里的值放入ecx寄存器里
0040D72D?????? mov???????? ecx,dword ptr [ebp+8]
;進(jìn)行累加運(yùn)算
0040D730???? ??add???????? ecx,eax
;放回num地址處
0040D732?????? mov???????? dword ptr [ebp+8],ecx
;此處為return num 返回Add函數(shù)結(jié)束
0040D735?????? mov???????? eax,dword ptr [ebp+8]
大家通過(guò)閱讀匯編代碼,上下文聯(lián)系應(yīng)該就可以分析出來(lái),遞歸調(diào)用時(shí)候的每次參數(shù)遞減,進(jìn)行累加求和,正因?yàn)檫壿嬇c運(yùn)算的短路特點(diǎn)會(huì)先判斷左邊num的值是否減到了0來(lái)決定是否還算右邊的表達(dá)式,匯編代碼對(duì)應(yīng)num為0時(shí)JE比對(duì)跳轉(zhuǎn)到return處;而為假時(shí)繼續(xù)計(jì)算右邊表達(dá)式,進(jìn)行call命令遞歸調(diào)用,棧地址不斷變化直至0結(jié)束return返回。
大家仔細(xì)體會(huì)!
以上就是邏輯與運(yùn)算中短路的特點(diǎn)以及運(yùn)用短路來(lái)實(shí)現(xiàn)語(yǔ)句中斷的例子!邏輯或原理也相同,大家可以自行實(shí)驗(yàn)!歡迎討論!
C語(yǔ)言研究中心(www.sztianhecheng.cn)