首页
社区
课程
招聘
[旧帖] [原创]C程序使用不同函数调用约定调用汇编子过程 0.00雪花
发表于: 2010-5-1 23:40 2484

[旧帖] [原创]C程序使用不同函数调用约定调用汇编子过程 0.00雪花

2010-5-1 23:40
2484

弄了几天的C调用汇编子过程,现总结一下。

开发工具:VC ++ 6.0  MASM32

一、__cdecl调用方式

1.  在VC中新建Win32 Console Application, TestASM

2.  新建test.c

#include<stdio.h>

extern void swap(int *px, int *py);

int main(void)

{

       int a=1, b=2;

       printf("before swaping, a=%d, b=%d\n", a, b);

       swap(&a, &b);

       printf("after  swaping, a=%d, b=%d\n", a, b);

    return 0;

}

3.  使用UltraEdit编辑汇编程序swap.asm

.386

.MODEL FLAT, C

OPTION CASEMAP:NONE

.CODE

  swap PROC a:DWORD, b:DWORD

    PUSH ESI

    PUSH EDI

      MOV ESI, [EBP+8]

     MOV EAX, [ESI]    ;参数1的值->EAX

      MOV EDI, [EBP+12]

      XCHG EAX, [EDI]

      MOV [ESI], EAX

      POP EDI

      POP ESI

      RET

  swap ENDP

END

4.  将swap.asm添加到TestASM工程中

VC->Project->Add to project->Files, 文件类型选择“所有文件”,选中汇编源文件swap.asm并添加到工程
或直接编译swap.asm,将生成的swap.obj拷贝到工程目录下

5.  在VC中设置汇编程序编译选项

在VC的FileView中,右击swap.asm->Settings, 切换到“Custom Build”选项卡,

在“Command”中输入:ml /c /coff  $(InputName).asm,

“Output”中输入 :$(InputName).obj

6.  编译链接执行

双击test.c->Compile, 生成test.obj

双击swap.asm->Compile, 生成swap.obj

然后Build, 生成TestASM.exe

最后执行

结果如下:

before swaping, a=1, b=2

after  swaping, a=2, b=1

Press any key to continue

二、__stdcall调用方式

1.C源程序

#include<stdio.h>

extern void __stdcall swap(int *px, int *py);

int main(void)

{

       int a=1, b=2;

       printf("before swaping, a=%d, b=%d\n", a, b);

       swap(&a, &b);

       printf("after  swaping, a=%d, b=%d\n", a, b);

    return 0;

}

2. 汇编源程序

.386

.MODEL FLAT, STDCALL

OPTION CASEMAP:NONE

.CODE

  swap PROC a:DWORD, b:DWORD

    PUSH ESI

    PUSH EDI

      MOV ESI, [EBP+8]

     MOV EAX, [ESI]    ;参数1的值->EAX

      MOV EDI, [EBP+12]

      XCHG EAX, [EDI]

      MOV [ESI], EAX

      POP EDI

      POP ESI

      RET

  swap ENDP

END

三、总结

函数调用约定             __cdecl                   __stdcall

相同点               自右向左反序入栈

不同点
函数名修饰符           _FunctionName        _FunctionName@参数字节数

谁清理堆栈参数         调用者               被调用者

1.       自右向左反序入栈

0040105B   lea         edx,[ebp-8]

0040105E   push        edx

0040105F   lea         eax,[ebp-4]

00401062   push        eax

2.       函数名修饰符

使用dumpbin工具查看swap.obj

__cdecl调用约定: __swap

__stdcall调用约定:__swap@8

3.       谁清理堆栈参数

(1)__cdecl调用约定

调用者来清理,如下面的add esp, 8

8:        swap(&a, &b);

0040105B   lea         edx,[ebp-8]

0040105E   push        edx

0040105F   lea         eax,[ebp-4]

00401062   push        eax

00401063   call        @ILT+5(_swap) (0040100a)

00401068   add         esp,8

(2)__stdcall调用约定

被调用者负责清理,如下面的ret 8

7:        swap(&a, &b);

0040105B   lea         edx,[ebp-8]

0040105E   push        edx

0040105F   lea         eax,[ebp-4]

00401062   push        eax

00401063   call        @ILT+0(_swap@8) (00401005)



_swap@8:

004010AC   push        ebp

004010AD   mov         ebp,esp

004010AF   push        esi

004010B0   push        edi

004010B1   mov         esi,dword ptr [ebp+8]

004010B4   mov         eax,dword ptr [esi]

004010B6   mov         edi,dword ptr [ebp+0Ch]

004010B9   xchg        eax,dword ptr [edi]

004010BB   mov         dword ptr [esi],eax

004010BD   pop         edi

004010BE   pop         esi

004010BF   leave

004010C0   ret         8


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 370
活跃值: (52)
能力值: ( LV13,RANK:350 )
在线值:
发帖
回帖
粉丝
2
http://blog.csdn.net/zhangyang0402/archive/2010/05/01/5549266.aspx
不过看时间 我认为是同一个人
基础很好  加油了 邀请码以发
2010-5-5 13:52
0
雪    币: 76
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
多谢版主。我先发的blog,后来就发看雪上了。
2010-5-5 15:40
0
游客
登录 | 注册 方可回帖
返回
//