乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Enter和Leave指令

       fisher60 2011-08-16
      Leave指令很簡單,相當(dāng)于move esp,ebp和pop ebp。

        Enter SRC1,SRC2 也不復(fù)雜,只是不了解的話動(dòng)態(tài)調(diào)試起來會(huì)很暈,Enter作了下面的事。

        push ebp

        mov ebp,esp

        現(xiàn)在棧頂上是上一個(gè)函數(shù)的基地址(就是上一個(gè)函數(shù)里的ebp,剛被壓入;這個(gè)ebp很重要,習(xí)慣上進(jìn)入一個(gè)子函數(shù)時(shí),在call的時(shí)候自動(dòng)壓入call后面那條語句的epi,然后壓入ebp來保存這個(gè)即將被改變的ebp值,然后把ebp指向當(dāng)前的棧頂,這樣調(diào)用這個(gè)函數(shù)領(lǐng)空里用到的所有本地局部變量用ebp就能找到了,所以這時(shí)ebp的值叫基址),用這個(gè)剛保存的基址,去棧的深處(也不深,也就是調(diào)用本函數(shù)的父函數(shù)的領(lǐng)空)把這個(gè)基址上SRC2-1個(gè)內(nèi)容復(fù)制到棧頂往上的相同大小的空間里,最后再把ebp的值壓上去。

        上面這段話里莫名其妙的操作正好使用了SRC2那么大的??臻g。

        sub esp,SRC1

        就走了這四步,而除了第三步,剩下那三步大家都很熟悉(如果不熟這篇文章還不是你該看的時(shí)候)并且經(jīng)常自己會(huì)寫的。關(guān)鍵是這個(gè)第三步有什么用?

        很多書上都叫第二參數(shù)是“嵌套層數(shù)”。Bingo,很正解。比如說主程序調(diào)用了proc1,而proc1調(diào)用了proc2,而proc2調(diào)用了proc3……總之突然procN要調(diào)用procM(當(dāng)然N>M)中的一個(gè)局部變量,按照傳統(tǒng)的調(diào)用子函數(shù)編寫方法,這個(gè)訪問實(shí)現(xiàn)起來簡直無計(jì)可施。而如果你在proc1中用了個(gè) enter SRC1,1 ,proc2中用了個(gè) enter SRC1,2 ……這樣就有個(gè)簡單的方法了。假設(shè)procN中要被賦值的的變量是第一個(gè),procM中要被讀取的變量也是第一個(gè),在要賦值時(shí)這樣就可以:

        mov eax, DWORD PTR [ebp-4*M]

        ??;把procM的基地址暫存到eax里

        push DWORD PTR [eax-4*M-4]

       ?。话寻催@個(gè)地址找到的procM中的變量入棧(草,寄存器不夠使了)

        pop DWORD PTR [ebp-4*N-4]

       ??;出棧,把值賦給procN中的那個(gè)饑渴的變量。

        思考一下吧,很簡單??梢娨褂胑nter必須保證要訪問的那個(gè)proc到現(xiàn)在所處的proc之間的一系列proc都在開頭用了enter。當(dāng)然,當(dāng)SRC2為零時(shí)就無所謂了,而且比自己寫push ebp 和 mov ebp , esp省勁的多。這樣在一系列的enter作用下,到了procN時(shí),棧中最上面的一部分是procN的領(lǐng)空,而這個(gè)領(lǐng)空的內(nèi)容是這樣的(從下往上):返回procN-1(調(diào)用procN的proc)的地址(call是epi應(yīng)有的內(nèi)容);剛進(jìn)入procN的ebp,即procN-1的基址;大小為SRC2*4的一段指針列表(指向前面各個(gè)用了enter的proc的基址),這段類表的原理就是遞推的方法,其中SRC2*4-4的內(nèi)容是從procN-1的領(lǐng)空中復(fù)制的,為了能讓procN+1也能用enter創(chuàng)建一斷指針列表,列表最上面也要壓入指向procN自己基址的指針,雖然在procN中,這最后一個(gè)沒什么用處;然后是依據(jù)SRC1開辟的本地局部變量區(qū)域。其實(shí)這個(gè)結(jié)構(gòu)有個(gè)名字,堆棧楨,貌似《編譯原理》里會(huì)學(xué)到這個(gè)概念。利用堆棧楨,就可以方便的訪問之前嵌套了自己的各輩函數(shù)的本地局部變量??傊?,要使用這個(gè)功能,必須保證一路上都用了enter,否則即使procN用了enter,在復(fù)制procN-1的指針段的時(shí)候復(fù)制的東西根本不是指針,而是,比如procN-1的本地局部變量什么的(因?yàn)閜rocN-1根本沒有這么一段指針表?。?/p>

      下面給段代碼,可以動(dòng)態(tài)調(diào)試一下便于理解

          .486                                ; create 32 bit code
          .model flat, stdcall                ; 32 bit memory model
          option casemap :none                ; case sensitive


          .data


          .code
      proc5 proc
       enter 8,5
       mov DWORD PTR [ebp-4-4*5],54
       mov eax,DWORD PTR [ebp-4-4*0]
       push DWORD PTR [eax-4-4*1]
       pop DWORD PTR [ebp-4-4*5-4]
       ;這里把第二個(gè)本地變量設(shè)為proc1的值
       leave
       ret
      proc5 endp
      proc4 proc
       enter 4,4
       mov DWORD PTR [ebp-4-4*4],53
       call proc5
       leave
       ret
      proc4 endp
      proc3 proc
       enter 8,3
       mov DWORD PTR [ebp-4-4*3],52
       mov eax,DWORD PTR [ebp-4-4*1]
       push DWORD PTR [eax-4-4*2]
       pop DWORD PTR [ebp-4-4*3-4]
       ;這里把第二個(gè)本地變量設(shè)為proc2的值
       call proc4
       leave
       ret
      proc3 endp
      proc2 proc
       enter 4,2
       mov DWORD PTR [ebp-4-4*2],51
       call proc3
       leave
       ret
      proc2 endp
      proc1 proc
       enter 4,1
       mov DWORD PTR [ebp-4-4*1],50
       call proc2
       leave
       ret
      proc1 endp
      start:
       call proc1 
       ret
      end start
       

      通常在函數(shù)調(diào)用中使用堆棧來傳遞參數(shù),保存函數(shù)返回地址和為自動(dòng)變量分配內(nèi)存。

      通常在進(jìn)入函數(shù)中時(shí)有兩條命令,如下:

      push ebp  ; 保存上一個(gè)函數(shù)的棧幀基地址

      mov ebp,esp ; 設(shè)置新的函數(shù)棧幀基地址

      在返回函數(shù)前通常有如下兩條指令:

      mov esp,ebp ; 將當(dāng)前函數(shù)棧幀基地址保存到esp中

      pop ebp ; 恢復(fù)上一個(gè)函數(shù)的棧幀基地址

      這是前奏。。之后Intel又設(shè)計(jì)了兩條指令來簡化上面的兩個(gè)步驟,那就是ENTER和LEAVE指令。

      我先說LEAVE指令吧。。這條指令就相當(dāng)于 mov esp,ebp 和 pop ebp 兩條指令的執(zhí)行效果。

      而ENTER指令要麻煩一點(diǎn)。我先將它的指令格式列出來:

      ENTER A,B 

      A表示的是在棧上分配的臨時(shí)變量的空間大小,B表示詞法嵌套級(我英文不好,原英文是:lexical nesting level)

      A很容易理解,就是sub esp,N之類的指令,用來給當(dāng)前函數(shù)的棧幀分配局部變量空間。

      B我也不太明白啥意思。不過沒關(guān)系,一般這個(gè)值為0。

      舉個(gè)例子吧,例如:ENTER 4,0 相當(dāng)于如下三條指令:

      push ebp

      mov ebp,esp

      sub esp,4

      就這么簡單!但是這條enter指令也有一個(gè)先天上的不足,那就是速度慢。所以一般編譯器生成代碼時(shí)很少使用enter指令。還是用以前的老方法,倒是LEAVE指令經(jīng)常被用到。


       

        本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多