亚洲免费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)碼堆棧深度的方法
        无码va在线观看| 亚洲六月丁香色婷婷综合久久| 亚洲av毛片在线免费看| 18禁裸男晨勃露j毛网站| 99re热这里只有精品最新| 国产va在线播放| 亚洲精品中文字幕乱码无线| 中文字幕亚洲综合久久| 亚洲老妇色熟女老太| 国产自产c区| 亚洲av日韩精品一区二区| 极品尤物一区二区三区| 性色av无码不卡中文字幕| 久久婷婷国产精品香蕉| 亚洲综合中文日韩字幕| 亚洲av无码乱码在线观看性色| 欧美与黑人午夜性猛交久久久| 国产精品色内内在线播放| 亚洲天堂av一区二区三区不卡| 曰韩无码无遮挡a级毛片| 国产一区日韩二区欧美三区| 亚洲av色香蕉一区二区蜜桃| 狠色人妻丝袜中文字幕| 久久精品国产色蜜蜜麻豆| 日韩在线观看你懂的| 久久精品日韩免费视频| 人妻少妇看a偷人无码| av片在线观看免费| 国产盗摄XXXX视频XXXX| 一区二区三区视频亚洲| 亚洲精品无码久久久影院相关影片| 国产视频毛片| 国产在线播放免费人成视频播放| 色综合天天综合欧美综合| 在线观看国产成人av片| 69堂在线无码视频2020| 久久精品国产亚洲av成人文字| 人人妻人人爽人人澡欧美一区| 欧美在线日韩| 国产精品丝袜美女久久| 亚洲国产成人一区二区精品区|