关于调用约定
__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