关于调用约定

__pascal

这是 pascal 语言的调用约定,跟 __stdcall 一样,参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在EAX中。VC 中已经废弃了这种调用方式,因此在写 VC 程序时,建议使用 __stdcall 代替。

__thiscall

这是 C++ 语言特有的一种调用方式,用于类成员函数的调用约定。如果参数确定,this 指针存放于 ECX 寄存器,函数自身清理堆栈;如果参数不确定,this指针在所有参数入栈后再入栈,调用者清理栈。__thiscall 不是关键字,程序员不能使用。参数按照从右至左的方式入栈。

 

int Add(int a, int b)
{
    return a + b;
}

int __stdcall Sub(int a, int b)
{
    return a + b;
}

这两个函数的汇编唯一区别就是最后ret的时候跟不跟8

00D21690  push        ebp  
00D21691  mov         ebp,esp  
00D21693  sub         esp,0C0h  
00D21699  push        ebx  
00D2169A  push        esi  
00D2169B  push        edi  
00D2169C  lea         edi,[ebp-0C0h]  
00D216A2  mov         ecx,30h  
00D216A7  mov         eax,0CCCCCCCCh  
00D216AC  rep stos    dword ptr es:[edi]  
    return a + b;
00D216AE  mov         eax,dword ptr [a]  
00D216B1  add         eax,dword ptr [b]  
}
00D216B4  pop         edi  
00D216B5  pop         esi  
00D216B6  pop         ebx  
00D216B7  mov         esp,ebp  
00D216B9  pop         ebp  
00D216BA  ret
00D216D0  push        ebp  
00D216D1  mov         ebp,esp  
00D216D3  sub         esp,0C0h  
00D216D9  push        ebx  
00D216DA  push        esi  
00D216DB  push        edi  
00D216DC  lea         edi,[ebp-0C0h]  
00D216E2  mov         ecx,30h  
00D216E7  mov         eax,0CCCCCCCCh  
00D216EC  rep stos    dword ptr es:[edi]  
    return a + b;
00D216EE  mov         eax,dword ptr [a]  
00D216F1  add         eax,dword ptr [b]  
}
00D216F4  pop         edi  
00D216F5  pop         esi  
00D216F6  pop         ebx  
00D216F7  mov         esp,ebp  
00D216F9  pop         ebp  
00D216FA  ret         8  

 

posted on 2016-08-16 23:33  张十四  阅读(275)  评论(0编辑  收藏  举报

导航