标签:
调用约定指的是函数在调用时会按照不同规则,翻译成不同的汇编代码。这和参数的压栈顺序和栈的清理方式相关,也就是说不同的调用约定,这些方式会做相应改变。一般编译器是以默认的调用约定编译一份代码,但当一个项目使用不同调用约定的库会产生链接错误。
int __cdecl f1(int a) { return a +1; } int __stdcall f2(int b) { return b +1; } int __fastcall f3(int c) { return c +1; } int main() { //函数导出名为_f1、_f2@4、@f3@4 int i = f1(1); int j = f2(2); int k = f3(3); return0; } @f3@4: 00000000:55 push ebp 00000001:8B EC mov ebp,esp 00000003:81 EC CC 000000 sub esp,0CCh 00000009:53 push ebx 0000000A:56 push esi 0000000B:57 push edi 0000000C:51 push ecx 0000000D:8D BD 34 FF FF FF lea edi,[ebp+FFFFFF34h] 00000013: B9 33000000 mov ecx,33h 00000018: B8 CC CC CC CC mov eax,0CCCCCCCCh 0000001D: F3 AB rep stos dword ptr es:[edi] 0000001F:59 pop ecx 00000020:894D F8 mov dword ptr [ebp-8],ecx 00000023:8B45 F8 mov eax,dword ptr [ebp-8] 00000026:83 C0 01 add eax,1 00000029:5F pop edi 0000002A:5E pop esi 0000002B:5B pop ebx 0000002C:8B E5 mov esp,ebp 0000002E:5D pop ebp 0000002F: C3 ret _f1: 00000000:55 push ebp 00000001:8B EC mov ebp,esp 00000003:81 EC C0 000000 sub esp,0C0h 00000009:53 push ebx 0000000A:56 push esi 0000000B:57 push edi 0000000C:8D BD 40 FF FF FF lea edi,[ebp+FFFFFF40h] 00000012: B9 30000000 mov ecx,30h 00000017: B8 CC CC CC CC mov eax,0CCCCCCCCh 0000001C: F3 AB rep stos dword ptr es:[edi] 0000001E:8B4508 mov eax,dword ptr [ebp+8] 00000021:83 C0 01 add eax,1 00000024:5F pop edi 00000025:5E pop esi 00000026:5B pop ebx 00000027:8B E5 mov esp,ebp 00000029:5D pop ebp 0000002A: C3 ret _f2@4: 00000000:55 push ebp 00000001:8B EC mov ebp,esp 00000003:81 EC C0 000000 sub esp,0C0h 00000009:53 push ebx 0000000A:56 push esi 0000000B:57 push edi 0000000C:8D BD 40 FF FF FF lea edi,[ebp+FFFFFF40h] 00000012: B9 30000000 mov ecx,30h 00000017: B8 CC CC CC CC mov eax,0CCCCCCCCh 0000001C: F3 AB rep stos dword ptr es:[edi] 0000001E:8B4508 mov eax,dword ptr [ebp+8] 00000021:83 C0 01 add eax,1 00000024:5F pop edi 00000025:5E pop esi 00000026:5B pop ebx 00000027:8B E5 mov esp,ebp 00000029:5D pop ebp 0000002A: C2 0400 ret 4 _main: 00000000:55 push ebp 00000001:8B EC mov ebp,esp 00000003:81 EC E4 000000 sub esp,0E4h 00000009:53 push ebx 0000000A:56 push esi 0000000B:57 push edi 0000000C:8D BD 1C FF FF FF lea edi,[ebp-0E4h] 00000012: B9 39000000 mov ecx,39h 00000017: B8 CC CC CC CC mov eax,0CCCCCCCCh 0000001C: F3 AB rep stos dword ptr es:[edi] 0000001E:6A01 push 1 00000020: E8 00000000 call _f1 00000025:83 C4 04 add esp,4 00000028:8945 F8 mov dword ptr [ebp-8],eax 0000002B:6A02 push 2 0000002D: E8 00000000 call _f2@4 00000032:8945 EC mov dword ptr [ebp-14h],eax 00000035: B9 03000000 mov ecx,3 0000003A: E8 00000000 call @f3@4 0000003F:8945 E0 mov dword ptr [ebp-20h],eax 00000042:33 C0 xor eax,eax 00000044:5F pop edi 00000045:5E pop esi 00000046:5B pop ebx 00000047:81 C4 E4 000000 add esp,0E4h 0000004D:3B EC cmp ebp,esp 0000004F: E8 00000000 call __RTC_CheckEsp 00000054:8B E5 mov esp,ebp 00000056:5D pop ebp 00000057: C3 ret
1 //把获得obj函数导出名,存储到d:\\1.txt文件 2 dumpbin OBJ文件路径/all /rawdata:none > d:\\1.txt 3 4 //获得汇编代码,存储到d:\\2.txt 5 dumpbin OBJ文件路径/disasm d:\\2.txt
1 extern"C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistry) 2 { 3 //do something 4 return STATUS_SUCCESS; 5 }
#ifdef __cplusplus extern"C" { #endif #include<NTDDK.h> #ifdef __cplusplus } #endif
【原创+整理】简述何为调用约定,函数导出名以及extern C
标签:
原文地址:http://www.cnblogs.com/cposture/p/4686480.html