Chinaunix首页 | 论坛 | 博客
  • 博客访问: 624323
  • 博文数量: 127
  • 博客积分: 6136
  • 博客等级: 准将
  • 技术积分: 1461
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 00:32

分类: WINDOWS

2009-12-22 22:02:47

    调用约定是指函数在被调用时,会按照不同的规则翻译成不同的汇编代码。用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) |
给主人留下些什么吧!~~