亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        用匯編語言剖析遞歸算法的內(nèi)在機(jī)理

        2012-12-22 11:47:00火善棟楊旭東
        重慶三峽學(xué)院學(xué)報 2012年3期
        關(guān)鍵詞:函數(shù)調(diào)用匯編語言堆棧

        火善棟 楊旭東

        (1.重慶三峽學(xué)院,重慶萬州 404000)

        (2.重慶安全技術(shù)職業(yè)學(xué)院,重慶萬州 404000)

        0 引 言

        遞歸算法是計算機(jī)領(lǐng)域中一個很重要的算法,通過遞歸算法可以使很復(fù)雜的問題變得很容易解決,例如著名的漢諾塔問題,假若不采用遞歸算法的話可能無法解決,還有數(shù)據(jù)結(jié)構(gòu)中樹和圖的遍歷,通過采用遞歸算法從而使問題變得非常容易,當(dāng)然遞歸算法在很多地方也有著很廣泛的應(yīng)用.

        遞歸算法雖然編寫起來比較容易,但在對遞歸算法的理解上,很多人卻感到很抽象,在學(xué)習(xí)過程中往往對這類問題的執(zhí)行過程不了解,對遞歸問題的認(rèn)識不清楚,所以難以寫出正確的遞歸程序,另外,在對遞歸算法的執(zhí)行效率以及空間復(fù)雜度上很多人更是感到難以理解.這其中一個很重要的原因就是對遞歸算法的內(nèi)在機(jī)理沒有搞清楚,對遞歸算法中函數(shù)如何反復(fù)調(diào)用以及參數(shù)如何進(jìn)行傳遞沒有理解透徹.

        由于高級語言把程序運行的內(nèi)部細(xì)節(jié)都透明化了,所以想通過高級語言理解遞歸算法的內(nèi)在運行機(jī)理是不可能的,但匯編語言是一門低級語言,其實質(zhì)也是機(jī)器語言一對一的符號化,是指令級的語言,雖然通過匯編語言編寫程序代碼費時費力,但通過匯編語言可以看出程序運行的每一個細(xì)節(jié).因此,這對理解遞歸算法無疑是一個很好的工具.

        1 實例分析

        本文通過一個很簡單的遞歸算法的例子“斐波那契(Fibonacci)數(shù)列”來具體剖析遞歸算法的內(nèi)在運行機(jī)理,從而加深對遞歸算法的理解,進(jìn)而幫助讀者更好地用好遞歸算法.

        【問題】編寫計算斐波那契(Fibonacci)數(shù)列的第n項函數(shù)fib(n).

        斐波那契數(shù)列為:0、1、1、2、3、……,即:

        fib(0)=0;

        fib(1)=1;

        fib(n)=fib(n-1)+fib(n-2) (當(dāng)n>1時)

        寫成遞歸函數(shù)通常是:

        為了使這個簡單的遞歸算法更具有代表性以及分析在遞歸算法內(nèi)部參數(shù)是如何傳遞的,本文把上述代碼改寫成“表1”左面所示的形式(C語言代碼).

        “表 1”是“斐波那契(Fibonacci)數(shù)列”遞歸算法的C語言實現(xiàn)代碼以及對應(yīng)的反匯編代碼,“圖 1”是通過分析反匯編代碼得出的該算法的堆棧變化示意圖.

        從下面這段反匯編代碼中可以看出,C程序中的遞歸函數(shù)對應(yīng)的反匯編代碼是一個遠(yuǎn)調(diào)用子過程,其整個調(diào)用過程的基本情況和執(zhí)行過程如下:

        1.1 進(jìn)行函數(shù)調(diào)用時首先將函數(shù)的參數(shù)(形參)壓入堆棧(在C語言中壓入的順序是從右到左,由于本實例只有一個參數(shù),所以沒有反應(yīng)出來),本例是通過SI寄存器來實現(xiàn)這一過程的.

        1.2 將函數(shù)的返回地址即該函數(shù)下一條將要執(zhí)行指令的地址壓入堆棧(由于本實例是遠(yuǎn)調(diào)用,所以將CS和IP的值壓入了堆棧)同時修改CS和IP寄存器的值,跳轉(zhuǎn)到要執(zhí)行指令的起始位置,從而實現(xiàn)了函數(shù)的調(diào)用.

        1.3 將BP的值壓入堆棧保護(hù)BP寄存器的值為以后恢復(fù)棧頂指針(SP)做準(zhǔn)備,然后將SP的值賦給BP,再通過BP訪問堆棧中傳入?yún)?shù)和函數(shù)體內(nèi)部定義的局部變量.

        1.4 將函數(shù)體內(nèi)部定義的局部變量壓入堆棧,本實例定義了三個局部變量,但只壓入了兩個,這個過程是通過SUB SP 4來實現(xiàn)的,有一個作為返回值沒有壓入.

        1.5 為了保證函數(shù)調(diào)用的透明性,將其調(diào)用過程中要用到寄存器的值(SI,DI)壓入堆棧.

        1.6 以上過程為函數(shù)體代碼的執(zhí)行作好了準(zhǔn)備,緊接的過程就是通過BP來實現(xiàn)函數(shù)參數(shù)的傳遞,并將中間結(jié)果保存在局部變量中,這一過程全部是通過對堆棧的操作來實現(xiàn)的.

        表1 斐波那契數(shù)列遞歸調(diào)用C語言與匯編代碼對比表

        圖1 堆棧變化示意圖

        1.7 每一次函數(shù)調(diào)用結(jié)束之后,恢復(fù)中間寄存器(本實例是SI,DI)以及SP,BP的值,本實例通過POP DI,POP SI,MOV SP,BP以POP BP來實現(xiàn)的.返回結(jié)果最后保存在AX寄存中,在本實例中函數(shù)體內(nèi)部的遞歸調(diào)用也是通過AX來實現(xiàn)參數(shù)傳遞的.另外由于主函數(shù)體的調(diào)用是一個FAR調(diào)用,而函數(shù)體內(nèi)部調(diào)用是一個near調(diào)用,為了實現(xiàn)遞歸調(diào)用過程的統(tǒng)一性,本實例通過PUSH CS和這一條指令來實現(xiàn)了遞歸調(diào)用的一致性工作,從而保證了代碼執(zhí)行的高效性.

        1.8 函數(shù)調(diào)用結(jié)束之后,SP和BP基本恢復(fù)為調(diào)用前的初始狀態(tài),但函數(shù)在執(zhí)行retf指令之后,堆棧還沒有完全清空,里面還保留著傳入?yún)?shù)的值,所以本實例通過POP CX這一指令來實現(xiàn)了清棧工作(這一情況會隨傳入?yún)?shù)個數(shù)的不同而有不同).

        總之,函數(shù)在執(zhí)行調(diào)用之后,堆棧完全恢復(fù)為調(diào)用前的最初始狀態(tài),只是結(jié)果保存在AX寄存器中,進(jìn)而實現(xiàn)了函數(shù)調(diào)用的透明性.

        筆者認(rèn)為,理解遞歸調(diào)用的一個重要難點就是要搞清楚在遞歸調(diào)用內(nèi)部是如何進(jìn)行參數(shù)傳遞的,以及返回值是如何保存的.通過對以上反匯編代碼的分析可以看出,AX寄存器起到了一個很重要的作用,以AX寄存器作為橋梁,不斷地和堆棧交換數(shù)據(jù),不斷地將中間結(jié)果保存在AX寄存器中,從而很輕松地實現(xiàn)了參數(shù)的傳遞和結(jié)果的保存.

        通過以上分析,可以得出“斐波那契(Fibonacci)數(shù)列”遞歸算法(n=5)的具體執(zhí)行過程,如圖 2所示:

        圖2 遞歸調(diào)用示意圖

        從圖二中可以看出,“斐波那契(Fibonacci)數(shù)列”遞歸算法的遞歸調(diào)用過程非常像一顆二叉樹中的前序遍歷,這是由于遞歸函數(shù)體fibo(n)中有兩個函數(shù)體fibo(n-1)和fibo(n-2)所造成的,由此可以推出當(dāng)遞歸函數(shù)體有三個甚至n個函數(shù)體的情況,當(dāng)然當(dāng)遞歸函數(shù)體只有一個函數(shù)體時,這是一種最簡單的遞歸調(diào)用形式.

        2 結(jié) 論

        遞歸算法實質(zhì)就是一個函數(shù)體不斷調(diào)用自身的過程,在調(diào)用的過程中不斷地將參數(shù)、返回地址以及局部變量壓入堆棧,當(dāng)返回時又將堆?;謴?fù)到每一次調(diào)用前的狀態(tài).在整個調(diào)用過程中,始終以AX或EAX寄存器作為橋梁,不斷地和堆棧交換數(shù)據(jù),不斷地將中間結(jié)果保存在AX或EAX寄存器中,從而順利地實現(xiàn)了參數(shù)的傳遞和結(jié)果的返回.另外,遞歸函數(shù)在執(zhí)行遞歸調(diào)用的過程,要不斷地執(zhí)行進(jìn)棧和出棧操作,所以執(zhí)行效率相對要低一些;同時,遞歸算法內(nèi)存的消耗也主要是用在堆棧的花銷上,但堆棧對內(nèi)存的占用是一個不斷變化的動態(tài)過程,因此,其最大占用內(nèi)存是由遞歸調(diào)用的最深層次決定的.

        就對遞歸算法的理解而言,我們可以將其視為一個樹形結(jié)構(gòu),當(dāng)遞歸函數(shù)體中有兩個遞歸函數(shù)時,其執(zhí)行過程類似于二叉樹的前序遍歷.推而廣之,當(dāng)遞歸函數(shù)體中有n個遞歸函數(shù)時,就相當(dāng)于這顆樹中有n個分枝,也就是形式上的“n叉樹”.

        [1]譚文等.天書夜讀:從匯編語言到 Windows內(nèi)核編程[M].北京:電子工業(yè)出版社,2008,10.

        [2]火善棟.通過匯編語言理解函數(shù)調(diào)用的內(nèi)在機(jī)理[J].計算機(jī)時代,2010(7).

        [3]呂鳳翥.C++語言程序設(shè)計[M].北京:清華大學(xué)出版社,2003,7.

        [4]卜艷萍.匯編語言程序設(shè)計教程:第二版[M].北京:清華大學(xué)出版社,2008,7.

        [5]邵桂芳,李剛,張小川.多媒體技術(shù)在匯編語言程序設(shè)計課程中的應(yīng)用[J].重慶工學(xué)院學(xué)報:自然科學(xué)版,2007(11).

        [6]楊隆平.SQL語言在VB中的優(yōu)化應(yīng)用[J].重慶三峽學(xué)院學(xué)報,2010(3).

        猜你喜歡
        函數(shù)調(diào)用匯編語言堆棧
        基于C語言的數(shù)學(xué)菜單的設(shè)計與實現(xiàn)
        高等學(xué)校計算機(jī)專業(yè)課程教學(xué)改革實踐——以匯編語言與接口技術(shù)課程為例
        匯編語言與C語言的混合程序設(shè)計技術(shù)研究
        電子制作(2019年10期)2019-06-17 11:45:16
        基于函數(shù)調(diào)用序列模式和函數(shù)調(diào)用圖的程序缺陷檢測方法*
        嵌入式軟件堆棧溢出的動態(tài)檢測方案設(shè)計*
        提高《匯編語言程序設(shè)計》教學(xué)效率的思考與實踐
        探討C++編程中避免代碼冗余的技巧
        基于堆棧自編碼降維的武器裝備體系效能預(yù)測
        Unity3D項目腳本優(yōu)化分析與研究
        中國新通信(2017年1期)2017-03-08 03:12:21
        一種用于分析MCS-51目標(biāo)碼堆棧深度的方法
        成人影院在线视频免费观看| 一区二区韩国福利网站| 欧洲一卡2卡三卡4卡免费网站| 成人白浆超碰人人人人 | 国精产品一区一区二区三区mba| 亚洲精品无码不卡在线播he| 亚洲人精品午夜射精日韩| 欧美成人精品a∨在线观看| 亚洲色成人www永久在线观看| 中文字幕一区二区三区精华液| 亚洲国产精品午夜电影| 日本看片一区二区三区| 久久亚洲宅男天堂网址| 视频一区视频二区自拍偷拍| 丰满的少妇av一区二区三区| 免费观看91色国产熟女| 欧洲女人与公拘交酡视频| 免费观看又色又爽又黄的| 久久精品免费无码区| 熟女人妻一区二区在线观看| 亚洲精品中文字幕导航| 私人vps一夜爽毛片免费| 大肉大捧一进一出好爽视频mba | 日韩无码尤物视频| 国产一区二区三区av香蕉| 日韩中文字幕不卡在线| 成人试看120秒体验区| 亚洲av成人无码久久精品| 9丨精品国产高清自在线看| 黄网站a毛片免费观看久久| 偷窥偷拍一区二区三区| 亚洲啪啪视频一区二区| 尤物网址在线观看| 久久精品成人欧美大片| 国产精品国产三级国产av创 | 久久国产色av免费观看| 精品国产乱码久久久久久1区2区| 国内精品人妻无码久久久影院94 | 亚洲一区日本一区二区| 国产免费在线观看不卡| 人妻无码一区二区不卡无码av|