• <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>

            兔子的技術(shù)博客

            兔子

               :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              202 Posts :: 0 Stories :: 43 Comments :: 0 Trackbacks

            留言簿(10)

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            這幾天學(xué)習(xí)匯編,分析了一下 c++ 中函數(shù)調(diào)用(cdecl 和 fastcall 方式)過程的匯編碼,記錄如下:

             

            程序例子

            struct tagTest 
            {
             int n1;
             long n2;
             DWORD n3;
            };

             

            long funtest1(tagTest p1,int p2,LPCTSTR lpszP3) 

            {  // 普通函數(shù)
             p1.n1 = 3;
             LPCTSTR lpszxx = lpszP3;
             p1.n3 = p2;

             return 300;

            }

             

            long __stdcall funtest2(tagTest p1,int p2,LPCTSTR lpszP3)

            { // stdcall 函數(shù)
             p1.n1 = 3;
             LPCTSTR lpszxx = lpszP3;
             p1.n3 = p2;

             return 300;

            }

            1、普通調(diào)用(cdecl)。

                調(diào)用方 C++ 代碼:

             long ixx = 0;
             tagTest tag1={34,6,87};
             ixx = funtest1(tag1,i2,"asdffffffdddddd");

                生成的匯編碼:

             long ixx = 0;
            0104171E  mov         dword ptr [ixx],0

             tagTest tag1={34,6,87};
            01041738  mov         dword ptr [tag1],22h     ; 成員賦值
            0104173F  mov         dword ptr [ebp-10h],6    ; 成員賦值
            01041746  mov         dword ptr [ebp-0Ch],57h  ; 成員賦值
             ixx = funtest1(tag1,i2,"asdffffffdddddd");
            0104174D  push        offset CAnonymousAsmTestApp::`vftable'+0F4h (11E60B0h) ; 入棧參數(shù)

                                      ; "asdffffffdddddd" 的地址。這里顯示似乎有問題(實(shí)際地址是對(duì)的)
            01041752  mov         edx,dword ptr [i2] 
            01041755  push        edx                 ; 入棧參數(shù) i2
            01041756  sub         esp,0Ch             ; 在棧中分配參數(shù) tag1 的空間
            01041759  mov         eax,esp
            0104175B  mov         ecx,dword ptr [tag1]
            0104175E  mov         dword ptr [eax],ecx  ; 入棧 tag1.n1
            01041760  mov         edx,dword ptr [ebp-10h]
            01041763  mov         dword ptr [eax+4],edx  ; 入棧 tag1.n2
            01041766  mov         ecx,dword ptr [ebp-0Ch]
            01041769  mov         dword ptr [eax+8],ecx  ; 入棧 tag1.n3
            0104176C  call        funtest1 (1041680h)   ; 調(diào)用函數(shù)。

                                   ;注意:這里同時(shí)將返回地址(下條指令的地址) 也入棧(這里是4字節(jié));

                                   ;   所以,函數(shù)中取得參數(shù)時(shí),需要從當(dāng)前 ESP 中加上 4 字節(jié)!
            01041771  add         esp,14h              ; 由調(diào)用者清參數(shù)棧
            01041774  mov         dword ptr [ixx],eax  ; 獲取返回值

             

            注意:已經(jīng)關(guān)閉了編譯器的某些優(yōu)化選項(xiàng),使匯編碼更易讀!

                調(diào)用方代碼總結(jié):

            • 參數(shù)從右向左依次入棧。
            • 棧指針(ESP)從底部向頂部依次減小。也就是說,棧頂?shù)刂沸。粭5椎刂反蟆?/div>
            • 如果參數(shù)是結(jié)構(gòu)(struct),則直接移動(dòng)棧頂指針,預(yù)留出結(jié)構(gòu)的大小;然后用 mov 指令逐步將成員拷貝到預(yù)留出來的??臻g!
            • call 指令調(diào)用目標(biāo)地址
            • 調(diào)用方清棧
            • 獲得返回值

                函數(shù)中生成的匯編碼

            long funtest1(tagTest p1,int p2,LPCTSTR lpszP3)
            {

             

            00351680  push        ebp    ; 基址指針入棧
            00351681  mov         ebp,esp  ; 將函數(shù)入口點(diǎn)的棧指針作為當(dāng)前基址指針。

                                           ;顧名思義,基址指針就是進(jìn)入函數(shù)時(shí)的棧頂指針!
            00351683  push        ecx     ; 在棧中分配局部變量空間。

                                          ;ecx 中的值無關(guān)緊要,只是預(yù)留一個(gè) 4 字節(jié)空間而已
             p1.n1 = 3;
            00351684  mov         dword ptr [p1],3  ; 賦值
             LPCTSTR lpszxx = lpszP3;
            0035168B  mov         eax,dword ptr [lpszP3] ; [lpszP3] 地址應(yīng)該就是 ebp - 4
            0035168E  mov         dword ptr [lpszxx],eax ; 賦值(通過 eax)
             p1.n3 = p2;
            00351691  mov         ecx,dword ptr [p2]
            00351694  mov         dword ptr [ebp+10h],ecx ; 賦值(通過 ecx)
             return 300;
            00351697  mov         eax,12Ch    ; 返回值放在 eax
            }
            0035169C  mov         esp,ebp  ; 恢復(fù)棧:清除局部變量
            0035169E  pop         ebp      ; 恢復(fù)基址指針
            0035169F  ret                  ; 返回(從棧中彈出返回地址,然后 jmp

             

             

            2、_stdcall調(diào)用。

                調(diào)用方 C++ 代碼:

             int i2=3;
             long ixx = 0;

             tagTest tag1={34,6,87};

             ixx = funtest2(tag1,i2,"asdffffffdddddd");

                生成的匯編碼:

             int i2=3;
            010A1759  mov         dword ptr [i2],3
             long ixx = 0;
            010A1760  mov         dword ptr [ixx],0

             tagTest tag1={34,6,87};
            010A1767  mov         dword ptr [tag1],22h
            010A176E  mov         dword ptr [ebp-0Ch],6
            010A1775  mov         dword ptr [ebp-8],57h

             ixx = funtest2(tag1,i2,"asdffffffdddddd");
            010A177C  push        offset CAnonymousAsmTestApp::`vftable'+104h (12460C0h) ; 入棧參數(shù)

                                      ; "asdffffffdddddd" 的地址。這里顯示似乎有問題(實(shí)際地址是對(duì)的)

                                      ; 和 cdecl 一樣,參數(shù)從右邊開始入棧


            010A1781  mov         eax,dword ptr [i2]
            010A1784  push        eax 
            010A1785  sub         esp,0Ch
            010A1788  mov         ecx,esp
            010A178A  mov         edx,dword ptr [tag1]
            010A178D  mov         dword ptr [ecx],edx
            010A178F  mov         eax,dword ptr [ebp-0Ch]
            010A1792  mov         dword ptr [ecx+4],eax
            010A1795  mov         edx,dword ptr [ebp-8]
            010A1798  mov         dword ptr [ecx+8],edx
            010A179B  call        funtest2 (10A16B0h)
            010A17A0  mov         dword ptr [ixx],eax  ; 取得返回值。

                                                       ; 注意:這里沒有清棧的代碼,由函數(shù)自己清棧

             

            注意:已經(jīng)關(guān)閉了編譯器的某些優(yōu)化選項(xiàng),使匯編碼更易讀!

                調(diào)用方代碼總結(jié):

            • 參數(shù)從右向左依次入棧。
            • 棧指針(ESP)從底部向頂部依次減小。也就是說,棧頂?shù)刂沸?;棧底地址大?/div>
            • 如果參數(shù)是結(jié)構(gòu)(struct),則直接移動(dòng)棧頂指針,預(yù)留出結(jié)構(gòu)的大小;然后用 mov 指令逐步將成員拷貝到預(yù)留出來的棧空間!
            • call 指令調(diào)用目標(biāo)地址
            • 返回時(shí),由函數(shù)自己清棧(通過 ret 指令)
            • 獲得返回值

                函數(shù)中生成的匯編碼

            long __stdcall funtest2(tagTest p1,int p2,LPCTSTR lpszP3)
            {
            010A16B0  push        ebp 
            010A16B1  mov         ebp,esp
            010A16B3  push        ecx  
             p1.n1 = 3;
            010A16BD  mov         dword ptr [p1],3
             LPCTSTR lpszxx = lpszP3;
            010A16C4  mov         eax,dword ptr [lpszP3]
            010A16C7  mov         dword ptr [lpszxx],eax
             p1.n3 = p2;
            010A16CA  mov         ecx,dword ptr [p2]
            010A16CD  mov         dword ptr [ebp+10h],ecx

             return 300;
            010A16D0  mov         eax,12Ch
            }
            010A16D5  mov         esp,ebp
            010A16D7  pop         ebp 
            010A16D8  ret         14h    ; 返回并清棧。

                                        ;(從棧中彈出返回地址,返回;然后ESP增加14H,14H為參數(shù)棧的字節(jié)數(shù))

            posted on 2009-08-14 15:06 會(huì)飛的兔子 閱讀(357) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 系統(tǒng)API,底層技術(shù)
            久久人搡人人玩人妻精品首页 | 亚洲国产精品成人久久蜜臀| 一本一本久久a久久精品综合麻豆| 嫩草伊人久久精品少妇AV| 日韩亚洲欧美久久久www综合网| 久久九色综合九色99伊人| 97精品伊人久久久大香线蕉| 91久久精品电影| 色8久久人人97超碰香蕉987| 久久99精品久久久久久秒播| 人妻无码久久一区二区三区免费 | 精品久久久久久国产91| 色99久久久久高潮综合影院| 久久久无码精品亚洲日韩按摩| 久久精品无码一区二区三区免费| 国产精品美女久久久m| 色综合久久中文字幕综合网| 情人伊人久久综合亚洲| 亚洲中文字幕久久精品无码APP| 久久久久国产成人精品亚洲午夜| 国内精品久久久久伊人av| 伊人色综合久久天天网| 久久香蕉国产线看观看99| 久久久久亚洲Av无码专| 亚洲国产欧美国产综合久久| 午夜视频久久久久一区| 久久久免费观成人影院| 精品人妻伦九区久久AAA片69 | 亚洲国产精品一区二区三区久久| 久久青青草原国产精品免费| 国产精品9999久久久久| 久久综合亚洲欧美成人| 欧美熟妇另类久久久久久不卡 | 激情综合色综合久久综合| 久久九九全国免费| 青青草原综合久久| 国产激情久久久久影院小草| 狠狠精品久久久无码中文字幕| 99久久夜色精品国产网站| 久久这里只有精品首页| 国产精品美女久久久网AV|