调用约定是指函数在被调用时,会按照不同的规则翻译成不同的汇编代码。用C或C++语言编译程序的时候,一般会有以下两种调用约定。
1.C语言调用约定。
c语言调用约定要求在生命函数时用__cdecl对函数进行修饰。如
void __cdecl foo(int a, int b);
c语言调用会在目标文件中产生一个符号来代表这个函数,此符号的形式为下划线+函数名,且函数以ret形式返回。例如:
foo(0x12345678, 0x11223344);
展成汇编代码如下:
push 0x11223344
push 0x12345678
call _foo
add esp, 8
2.标准调用约定。
要求在声明函数时用__stdcall对函数进行修饰。如
void __stdcall foo(int a, int b);
标准调用会在目标文件中产生一个符号来代表这个函数,此符号形式为下划线+函数名+X,其中X为清理堆栈时需要的数字,函数以ret X形式返回。
上例中展成汇编代码为:
push 0x11223344
push 0x12345678
call __foo@8
一般来说,很少见到用关键字指定函数的调用约定,编译器会选择默认的调用约定进行编译,在VC编译器中,默认使用C语言的调用约定。而Windows驱动程序的编写使用的是标准调用约定,尤其是入口函数。系统会寻找__DriverEntry@8作为程序的入口点,若用c的调用约定就会导致链接错误,因此在编译驱动是需要改变默认的调用约定。
若用DDK的编译环境则可忽略此项,因为DDK环境默认的就是标准调用约定。
阅读(1209) | 评论(0) | 转发(0) |