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

兔子的技術博客

兔子

   :: 首頁 :: 聯系 :: 聚合  :: 管理
  202 Posts :: 0 Stories :: 43 Comments :: 0 Trackbacks

留言簿(10)

最新評論

閱讀排行榜

評論排行榜

       現代的編程語言的函數竟然有那麼多的調用方式。這些東西要完全理解還得通過匯編代碼才好理解。他們各自有自己的特點
其實這些調用方式的差別在主要在一下幾個方面

1.參數處理方式(傳遞順序,存取(利用盞還是寄存器))
2.函數的結尾處理方式(善后處理)



以下是理論:
__cdecl    由調用者平棧,參數從右到左依次入棧 是C和C++程序的缺省調用方式。每一個調用它的函數都包含清空堆棧的代碼
所以產生的可執行文件大小會比調用_stdcall函數的大。函數采用從右到左的壓棧方式。VC將函數編譯后會在函數名前面加上
下劃線前綴。是MFC缺省調用約定
__stdcall ,WINAPI,CALLBACK ,PASCAL 由被調用者平棧,參數從右到左依次入棧 ._stdcall是Pascal程序的缺省調用方式,
通常用于Win32   Api中,函數采用從右到左的壓棧方式,自己在退出時清空堆棧。VC將函數編譯后會在函數名前面加上下劃
線前綴,在函數名后加上"@"和參數的字節數

__fastcall 由被調用者平棧,參數先賦值給寄存器,然后入棧 “人”如其名,它的主要特點就是快,因為它是通過寄存器來傳送參數的
(實際上,它用ECX和EDX傳送前兩個雙字(DWORD)或更小的參數,剩下的參數仍舊自右向左壓棧傳送,被調用的函數在返回前
清理傳送參數的內存棧),在函數名修飾約定方面,它和前兩者均不同.
_fastcall方式的函數采用寄存器傳遞參數,VC將函數編譯后會在函數名前面加上"@"前綴,在函數名后加上"@"和參數的字節數。 

__thiscall 由被調用者平棧,參數入棧,this 指針賦給 ecx 寄存器 僅僅應用于“C++”成員函數。this指針存放于CX寄存器,參數從右
到左壓。thiscall不是關鍵詞,因此不能被程序員指定。  


__declspec(naked) 這是一個很少見的調用約定,一般程序設計者建議不要使用。編譯器不會給這種函數增加初始化和清理代碼
更特殊的是,你不能用return返回返回值,只能用插入匯編返回結果。這一般用于實模式驅動程序設計.
以下是實踐:

  
int __stdcall test_stdcall(char para1, char para2)
{
    para1 
= para2;
    
return 0;
}
int __cdecl test_cdecl(char para, )
{
    
char    p = '\n';
    va_list marker;
    va_start( marker, para );
    
while( p != '\0' )
    {
        p 
= va_arg( marker, char);
        printf(
"%c\n", p);
    }
    va_end( marker );
    
return 0;
}

int pascal test_pascal(char para1, char para2)
{
    
return 0;
}

int __fastcall test_fastcall(char para1, char para2, char para3, char para4)
{
    para1 
= (char)1;
    para2 
= (char)2;
    para3 
= (char)3;
    para4 
= (char)4;
    
return 0;
}
__declspec(naked) 
void __stdcall test_naked(char para1, char para2)
{
    __asm
    {
        push    ebp
        mov     ebp, esp
        push    eax
        mov     al,
byte ptr [ebp + 0Ch]
        xchg    
byte ptr [ebp + 8],al      
        pop     eax
        pop     ebp
        ret     
8
    }
//    return ;
}


int main(int argc, char* argv[])
{
    test_stdcall( 
'a''b' );
    test_cdecl( 
'c','d','e','f','g' ,'h' ,'\0');
    test_pascal( 
'e''f' );
    test_fastcall( 
'g''h''i''j' );
    test_naked( 
'k''l');
    
return 0;
}
匯編代碼如下
int main(int argc, char* argv[])
{
00411350  push        ebp  
00411351  mov         ebp,esp 
00411353  sub         esp,0C0h 
00411359  push        ebx  
0041135A  push        esi  
0041135B  push        edi  
0041135C  lea         edi,[ebp
-0C0h] 
00411362  mov         ecx,30h 
00411367  mov         eax,0CCCCCCCCh 
0041136C  rep stos    dword ptr es:[edi] 
    test_stdcall( 
'a''b' );
0041136E  push        62h  
00411370  push        61h  
00411372  call        
_test_stdcall@8

    test_cdecl( 
'c','d','e','f','g' ,'h' ,'\0');
00411377  push        0    
00411379  push        68h  
0041137B  push        67h  
0041137D  push        66h  
0041137F  push        65h  
00411381  push        64h  
00411383  push        63h  
00411385  call        _test_cdecl

0041138A  add         esp,1Ch 
;恢復_test_cdecl參數壓入前的堆棧指令是: add esp,n*4 n=參數的數量
    test_fastcall( 'g''h''i''j' );
0041138D  push        6Ah  
0041138F  push        69h  
00411391  mov         dl,68h 
00411393  mov         cl,67h 
00411395  call        test_fastcall

    test_naked( 
'k''l');
0041139A  push        6Ch  
0041139C  push        6Bh  
0041139E  call        
_test_naked
    
return 0;
004113A3  xor         eax,eax 
}

int __stdcall test_stdcall(char para1, char para2)
{
004111F0  push        ebp  
004111F1  mov         ebp,esp 
004111F3  sub         esp,0C0h 
004111F9  push        ebx  
004111FA  push        esi  
004111FB  push        edi  
004111FC  lea         edi,[ebp-0C0h] 
00411202  mov         ecx,30h 
00411207  mov         eax,0CCCCCCCCh 
0041120C  rep stos    dword ptr es:[edi] ;初始edi
    para1 = para2;
0041120E  mov         al,byte ptr [para2] ;mov al,byte ptr[ebp+c]
00411211  mov         byte ptr [para1],al ;mov byte ptr[ebp+8],al

    return 0;
00411214  xor         eax,eax
00411216  pop         edi  
00411217  pop         esi  
00411218  pop         ebx  
00411219  mov         esp,ebp 
0041121B  pop         ebp  
0041121C ret      8 ;恢復到壓入函數參數前堆棧,由于有兩個參數所以ret 8 相當于 pop eip 然后esp+8
}
int __cdecl test_cdecl(char para,... )
{
00411230  push        ebp  
00411231  mov         ebp,esp 
00411233  sub         esp,0D8h 
0041123C  lea         edi,[ebp-0D8h] 
00411242  mov         ecx,36h 
00411247  mov         eax,0CCCCCCCCh 
0041124C  rep stos    dword ptr es:[edi] 
    char    p = '\n';
0041124E  mov         byte ptr [p],0Ah 
    va_list marker;
    va_start( marker, para );
00411252  lea         eax,[ebp+0Ch] 
00411255  mov         dword ptr [marker],eax 
    while( p != '\0' )
00411258  movsx       eax,byte ptr [p] 
0041125C  test        eax,eax 
0041125E  je          test_cdecl+60h (411290h) 
    {
        p = va_arg( marker, char);
00411260  mov         eax,dword ptr [marker] 
00411263  add         eax,4 
00411266  mov         dword ptr [marker],eax 
00411269  mov         ecx,dword ptr [marker] 
0041126C  mov         dl,byte ptr [ecx-4] 
0041126F  mov         byte ptr [p],dl 
        printf("%c\n", p);
00411272  movsx       eax,byte ptr [p] 
00411276  mov         esi,esp 
00411278  push        eax  
00411279  push        offset string "%c\n" (41401Ch) 
0041127E  call        dword ptr [__imp__printf (416180h)] 
00411284  add         esp,8 
0041128E  jmp         test_cdecl+28h (411258h) 
    }
    va_end( marker );
00411290  mov         dword ptr [marker],0 
    return 0;
00411297  xor         eax,eax 

004112A9  mov         esp,ebp 
004112AB  pop         ebp  
004112AC  ret    

}
     
int __fastcall test_fastcall(char para1, char para2, char para3, char para4)
{
004112D0  push        ebp  
004112D1  mov         ebp,esp 
004112D3  sub         esp,0D8h  
004112DD  lea         edi,[ebp-0D8h] 
004112E3  mov         ecx,36h 
004112E8  mov         eax,0CCCCCCCCh 
004112ED  rep stos    dword ptr es:[edi] 
004112EF  pop         ecx  
004112F0  mov         byte ptr [ebp-14h],dl 
004112F3  mov         byte ptr [ebp-8],cl 
    para1 = (char)1;
004112F6  mov         byte ptr [para1],1 
    para2 = (char)2;
004112FA  mov         byte ptr [para2],2 
    para3 = (char)3;
004112FE  mov         byte ptr [para3],3 
    para4 = (char)4;
00411302  mov         byte ptr [para4],4 
    return 0;
00411306  xor         eax,eax  

0041130B  mov         esp,ebp 
0041130D  pop         ebp  
0041130E  ret         8  
;由于使用了ecx ,edx 傳遞參數 本來4個參數只使用兩push 所以這里是 ret 4*2
}
     

__declspec(naked) void __stdcall test_naked(char para1, char para2)
{
00411330  push        ebp      ;這里編譯器沒加入任何初始化和清棧的指令,你代碼如何寫它就復制過來
00411331  mov         ebp,esp 
00411333  push        eax  
00411334  mov         al,byte ptr [para2]    
00411337  xchg        al,byte ptr [para1] 
0041133A  pop         eax  
0041133B  pop         ebp  
0041133C  ret         8  

posted on 2010-07-02 14:07 會飛的兔子 閱讀(675) 評論(0)  編輯 收藏 引用 所屬分類: C++庫,組件系統API,底層技術
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            在线性视频日韩欧美| 欧美~级网站不卡| 午夜一级在线看亚洲| 欧美精品乱码久久久久久按摩| 国产精品永久免费视频| 一区二区三区国产在线观看| 欧美肥婆在线| 久久久噜噜噜久久狠狠50岁| 韩国av一区二区三区| 久久国产精品黑丝| 亚洲一区综合| 国产精一区二区三区| 亚洲欧美一区二区三区在线| 一个色综合导航| 国产精品地址| 性做久久久久久久久| 亚洲综合精品四区| 卡通动漫国产精品| 999亚洲国产精| 久久精品导航| 在线观看日韩av电影| 久久久亚洲欧洲日产国码αv| 中日韩高清电影网| 国产欧美一区二区色老头 | 欧美黑人多人双交| 亚洲人人精品| 最新亚洲电影| 久久精品成人| 亚洲国产日韩美| 亚洲精品国产精品国自产观看浪潮 | 中国亚洲黄色| 国产一区二区你懂的| 久久香蕉国产线看观看av| 久久久青草婷婷精品综合日韩| 亚洲国产精品黑人久久久| 亚洲激情欧美| 国产精品自拍三区| 蜜桃av一区二区三区| 欧美精品在线网站| 欧美影院一区| 免费亚洲电影在线观看| 亚洲欧美日韩另类| 亚洲国产精品精华液网站| 91久久久国产精品| 国产女优一区| 亚洲日本精品国产第一区| 国产精品久久久久久久午夜片| 久久久久久久尹人综合网亚洲| 欧美成人r级一区二区三区| 亚洲欧美日韩成人| 免费欧美高清视频| 欧美一区二区三区视频在线| 麻豆成人在线| 久久电影一区| 欧美日韩免费观看一区二区三区| 久久国产欧美| 欧美午夜激情视频| 免费短视频成人日韩| 国产精品jizz在线观看美国| 久热精品在线视频| 国产精品青草久久| 亚洲国产精品成人久久综合一区| 国产精品影院在线观看| 亚洲精品国产欧美| 亚洲成色999久久网站| 亚洲一级二级| 中文精品在线| 美日韩在线观看| 久久国产精品亚洲77777| 欧美精品网站| 亚洲国产精品久久| 国产伦精品一区二区三区| 亚洲欧美国产精品va在线观看| 亚洲啪啪91| 久久国产天堂福利天堂| 亚洲在线中文字幕| 欧美另类视频| 欧美激情二区三区| 亚洲欧美一区二区原创| 午夜精品久久久久久久99热浪潮| 亚洲午夜精品| 亚洲自拍高清| 亚洲欧洲日韩综合二区| 亚洲免费av网站| 国产亚洲一区二区三区在线观看| 久久成人18免费观看| 久久亚洲精品网站| 亚洲国内精品在线| 欧美成人国产一区二区 | 欧美mv日韩mv国产网站| 国产精品一区二区你懂的| 久久久午夜精品| 国户精品久久久久久久久久久不卡| 久久久亚洲高清| 国产一区自拍视频| 牛牛影视久久网| 欧美日韩中文字幕| 欧美黄色小视频| 久久精品电影| 欧美一区二区三区免费在线看 | 久久蜜臀精品av| 亚洲区一区二| 性久久久久久久| 在线成人亚洲| 国产精品免费看久久久香蕉| 亚洲午夜精品国产| 亚洲第一级黄色片| 榴莲视频成人在线观看| 久久亚洲春色中文字幕| 亚洲在线一区二区| 亚洲国产天堂久久国产91| 母乳一区在线观看| 小处雏高清一区二区三区| 久久精品中文字幕免费mv| 亚洲性视频网站| 欧美成人网在线| 亚洲欧美日韩一区| 一区二区三区|亚洲午夜| 久久亚洲精品网站| 亚洲国产精品www| 国产精品一区二区女厕厕| 久久久久久久久久码影片| 久久综合狠狠| 亚洲欧美日韩精品| 美女在线一区二区| 欧美三区在线观看| 免费观看国产成人| 国产精品一区二区三区乱码 | 国精品一区二区| 亚洲精品一二| 伊人成年综合电影网| 亚洲欧美国产毛片在线| 亚洲精品偷拍| 狂野欧美一区| 另类春色校园亚洲| 国产日韩一级二级三级| 一区二区三区欧美视频| 夜夜爽www精品| 欧美国产日本在线| 欧美成人在线网站| 久久综合五月天婷婷伊人| 亚洲看片网站| 韩国免费一区| 欧美一区二区精品久久911| 亚洲影院一区| 国产精品影视天天线| 亚洲你懂的在线视频| 欧美伊人影院| 狠狠色综合网站久久久久久久| 久久午夜视频| 国产精品毛片大码女人| 99国内精品久久| 亚洲欧美中文日韩在线| 国产精品丝袜久久久久久app| 亚洲一区国产视频| 久久久青草青青国产亚洲免观| 悠悠资源网亚洲青| 欧美精品网站| 久久精品国产综合精品| 欧美激情精品久久久久| 正在播放欧美视频| 国产精品亚洲一区| 欧美成ee人免费视频| 亚洲午夜一区| 亚洲国产欧美精品| 99在线精品观看| 欧美高清你懂得| 一本色道久久88精品综合| 亚洲免费影院| 久久免费精品视频| 亚洲国产综合在线| 欧美久久久久久久| 一本色道久久加勒比88综合| 亚洲影视在线播放| 亚洲乱码国产乱码精品精可以看 | 欧美黄色日本| 国产一区二区三区av电影| 亚洲女人天堂成人av在线| 久久国产精品久久久久久久久久 | 欧美粗暴jizz性欧美20| 久久国产精品一区二区三区四区| 亚洲国产日韩综合一区| 亚洲影院免费| 91久久国产综合久久91精品网站| 久久九九免费视频| 欧美一区二区性| 欧美精品综合| 一区二区三区国产| 麻豆国产精品777777在线| 1000部精品久久久久久久久| 欧美午夜欧美| 亚洲一区二区伦理| 韩国亚洲精品| 欧美日韩免费观看一区=区三区| 亚洲欧美在线高清| 亚洲视频在线观看一区| 亚洲三级免费电影| 亚洲黄色影院| 日韩一区二区电影网| 亚洲国产专区校园欧美|