青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

loop_in_codes

低調做技術__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

一段tricky codes:函數調用的那些底層細節


有一天,被同事問到了下面這段代碼,就簡單分析了一下,發覺還有點意思:

__declspec(naked)
void call(void* pfn, 
{
    __asm 
    
{
        pop eax;
        add eax, 
3;
        xchg dword ptr[esp], eax;
        push eax;
        ret;
    }

}

 

再看它的用法:

 

void print_str( const char *s )
{
    printf( 
"%s\n", s );
}

call( print_str, 
"a string" );

 

call函數的大致作用,就是調用傳遞進去的函數print_str,并將參數"a string"傳遞給目標
函數。

但是它是怎么做到的呢?雖然call只有簡單的幾句匯編代碼,但是卻包含了很多函數在編譯
器中的匯編層實現。要了解這段代碼的意思,需要知道如下相關知識:

0、函數調用的實現中,編譯器通過系統堆棧(ESP寄存器指向)傳遞參數;
1、C語言默認的函數調用規則(_cdecl)中,調用者從右往左將參數壓入堆棧,并且調用者負
責堆棧平衡,也就是保證調用函數的前后,ESP不變;
2、匯編指令call本質上是先將返回地址,通常是該條指令的下一條指令壓入堆棧,然后直
接跳轉到目標位置;
3、匯編指令ret則是先從堆棧棧頂取出返回地址,然后跳轉過去;
4、匯編指令add加上其操作數,貌似占3個字節長度;
5、在visual studio中,DEBUG模式下編譯器會在我們的代碼中插入各種檢測代碼,而
__declspec(naked)則是告訴編譯器:別往這里添加代碼。

了解了以上常識后,再看這段代碼,其本質無非就是利用了這些規則,在代碼段跳來跳去。
我們來逐步分析一下:

在調用call函數的地方,大概的代碼為:

 

caller:
// 堆棧狀態,從左往右分別表示棧頂至下
// ret_addr是call后的地址,即add esp, 8的位置
// a1, a2表示函數參數,callee_addr是這里的print_str
// stack: ret_addr, callee_addr, a1, a2, 
call( print_str, "a string" ); 
add esp, 
8 //清除參數傳遞所占用的堆??臻g,維持堆棧平衡
end_label //位于add后的指令,后面會提到

call:
// 此時堆棧stack: ret_addr, a1, a2
pop eax // eax = ret_addr; stack: callee_addr, a1, a2, 
add eax, 3 // eax = end_label; stack: callee_addr, a1, a2, 
xchg dword ptr[esp], eax // eax = callee_addr; stack: end_label, a1, a2, 
push eax // stack: callee_addr, end_label, a1, a2, 
ret // 取出callee_addr并跳轉,也就跳轉到print_str函數的入口,此時堆棧
    
// stack: end_label, a1, a2, 

callee(print_str):

 無視函數內容

ret 
// print_str返回,此時正常情況下,堆棧stack: end_label, a1, a2, 
 
// 取出end_label并跳轉,stack: a1, a2, 

 

那么當callee結束時,則跳轉回caller函數中。不過,如過你所見,此時堆棧中還保留著再
調用call函數時傳入的參數:stack: a1, a2, ...,所以,DEBUG模式下,VS就會提示你堆
棧不平衡。這里簡單的處理就是手動來進行堆棧平衡:

 

    call( print_str, "a string" );
    __asm
    
{
        add esp, 
4
    }

 

傳入了多少個參數,就得相應地改變esp的值。

話說距離上篇博客都有半年了,自己都不知道時間晃得如此之快。最近業余折騰了下android開發
一不小心就跨年了。
 

posted on 2011-01-02 16:34 Kevin Lynx 閱讀(4930) 評論(4)  編輯 收藏 引用 所屬分類: c/c++

評論

# re: 一段tricky codes:函數調用的那些底層細節 2011-01-03 05:58 淘寶網

哈哈 不錯  回復  更多評論   

# re: 一段tricky codes:函數調用的那些底層細節 2011-01-06 12:30 miosys

整個懸念就是放在 add eax, 3;
這條指令就是為了在跳轉到最外層主調函數上時,留出一個指令空間來平棧。
如果用 ADD + WORD,應該是 3。當然不會BT到加 DWORD。  回復  更多評論   

# re: 一段tricky codes:函數調用的那些底層細節 2011-01-08 21:47 G++

圍觀,表示看不懂,哈哈哈哈哈~~~!  回復  更多評論   

# re: 一段tricky codes:函數調用的那些底層細節[未登錄] 2011-03-15 14:36 dophi

已閱  回復  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美成人午夜激情| 亚洲精品少妇30p| 欧美mv日韩mv国产网站| 久久久av水蜜桃| 久久久久国产精品厨房| 噜噜噜91成人网| 欧美va天堂va视频va在线| 欧美高清在线视频| 欧美日韩人人澡狠狠躁视频| 欧美日韩一区二区视频在线| 国产精品爽黄69| 精东粉嫩av免费一区二区三区| 伊人夜夜躁av伊人久久| 亚洲精品视频在线| 亚洲免费影视| 另类av一区二区| 亚洲国产精品久久| 99视频精品| 欧美在线日韩精品| 欧美母乳在线| 黑人一区二区三区四区五区| 夜夜嗨av一区二区三区网站四季av| 亚洲欧美在线播放| 欧美第十八页| 亚洲一区观看| 欧美精品成人91久久久久久久| 国产午夜精品一区二区三区欧美 | 欧美视频在线播放| 国产亚洲二区| 亚洲天堂偷拍| 欧美3dxxxxhd| 一区二区三区国产在线观看| 久久精品国产一区二区三区免费看 | 久久综合五月| 亚洲欧洲视频在线| 亚洲一区二区成人在线观看| 久久午夜视频| 欧美日韩一区二区三区视频| 国产欧美一区二区三区另类精品| 亚洲毛片网站| 久久久久在线观看| 中文国产成人精品久久一| 久久精品亚洲热| 国产精品久久久久免费a∨| 精品成人一区二区三区| 欧美一级夜夜爽| 亚洲片区在线| 欧美激情一区二区三区蜜桃视频 | 国产美女精品视频| 亚洲国产精品一区二区第四页av | 男女精品视频| 国产亚洲美州欧州综合国| 一区二区三区欧美激情| 欧美成人综合网站| 亚洲欧美国产精品桃花| 欧美日韩国产综合网| 亚洲精品资源| 欧美激情精品久久久久久免费印度| 亚洲欧美韩国| 国产老肥熟一区二区三区| 亚洲欧美中文另类| 99视频精品免费观看| 欧美日韩精品一区二区| 亚洲精品日日夜夜| 日韩一级精品视频在线观看| 久久综合伊人| 亚洲国产成人在线播放| 久久久99爱| 午夜精品久久久久久久99水蜜桃| 国产精品福利av| 亚洲女同精品视频| 午夜免费久久久久| 国产午夜精品久久久久久久| 久久久视频精品| 欧美中文字幕在线视频| 国产专区欧美精品| 久久夜色精品| 欧美激情精品久久久久久大尺度| 亚洲精品日韩在线观看| 在线天堂一区av电影| 国产精品美女| 久久综合成人精品亚洲另类欧美| 一区二区三区波多野结衣在线观看| 亚洲尤物影院| 先锋影院在线亚洲| 在线观看亚洲视频| 亚洲国产一区二区三区在线播 | 亚洲专区一区二区三区| 午夜亚洲福利| 91久久精品国产| 一区二区国产在线观看| 国内成人自拍视频| 亚洲三级国产| 国产一区二区三区直播精品电影| 欧美激情a∨在线视频播放| 欧美视频免费在线观看| 久久久精品日韩欧美| 欧美福利影院| 欧美制服第一页| 欧美日韩a区| 久久视频这里只有精品| 欧美韩日一区二区| 午夜亚洲福利| 欧美激情视频一区二区三区免费| 久久精品网址| 欧美日韩一区在线| 欧美大片第1页| 国产欧美一区二区视频| 91久久国产综合久久| 国产日韩成人精品| 日韩手机在线导航| 亚洲国产视频直播| 欧美伊人久久久久久久久影院| 99ri日韩精品视频| 久久久女女女女999久久| 香蕉久久久久久久av网站| 欧美激情在线免费观看| 蘑菇福利视频一区播放| 国产精品中文字幕欧美| av72成人在线| a4yy欧美一区二区三区| 老司机一区二区| 久久亚洲精品一区二区| 国产视频一区在线| 亚洲欧美精品一区| 午夜精品视频网站| 国产精品高潮呻吟久久| 一本高清dvd不卡在线观看| 亚洲精品免费在线播放| 免费看亚洲片| 国产精品豆花视频| 日韩一区二区精品在线观看| 亚洲国产高清自拍| 久久久久女教师免费一区| 久久精品视频免费播放| 国产一区二区三区在线观看精品 | 国产精品mm| 日韩一区二区精品视频| 久久婷婷综合激情| 欧美一区综合| 欧美寡妇偷汉性猛交| 欧美黄色一区| 亚洲精品久久久一区二区三区| 久久一日本道色综合久久| 蜜桃久久精品乱码一区二区| 樱花yy私人影院亚洲| 久久久一二三| 亚洲成人在线免费| 国产女人精品视频| 久久精品国产欧美亚洲人人爽| 久久欧美肥婆一二区| 韩国一区二区三区美女美女秀| 欧美自拍偷拍| 亚洲大片在线| 一区二区三区不卡视频在线观看| 欧美日韩国产成人在线免费 | 久久久久99| 欧美激情按摩在线| aa亚洲婷婷| 国产日韩欧美综合在线| 久久久久久久久久久成人| 欧美激情久久久久| 亚洲色图自拍| 国产真实久久| 欧美精品久久久久久久久老牛影院| 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 老**午夜毛片一区二区三区| 欧美激情免费在线| 亚洲综合电影| 在线观看日产精品| 欧美视频在线观看免费| 久久爱另类一区二区小说| 亚洲国产婷婷| 久久国产日韩欧美| 亚洲精选久久| 国产精自产拍久久久久久| 葵司免费一区二区三区四区五区| 一本久道久久综合狠狠爱| 久久精品视频免费播放| 99国产精品99久久久久久粉嫩| 国产日韩欧美精品| 欧美日韩亚洲三区| 久热成人在线视频| 亚洲男同1069视频| 亚洲区第一页| 欧美电影资源| 久久久99精品免费观看不卡| 亚洲午夜精品久久久久久浪潮| 尤物99国产成人精品视频| 国产精品av一区二区| 欧美a级在线| 久久精品一区二区三区四区 | 亚洲成人影音| 国产欧美一二三区| 欧美视频在线观看免费网址| 久久综合狠狠综合久久激情| 亚洲免费视频网站| 99精品欧美一区二区三区| 欧美激情网站在线观看| 蜜桃av综合|