stdcall调用分析

本文详细分析了stdcall调用约定在C语言环境下的工作原理,通过VC6.0 Debug版本的汇编代码展示了函数调用过程,包括参数传递、局部变量分配和释放。文章以stdcallFun和main函数为例,解释了stdcall调用约定的特点,如参数从右到左入栈,返回值存储在eax中,以及调用者清理堆栈的规则。同时指出,由于stdcall的特性,它不适用于参数个数可变的函数。最后,文章提到了main函数默认使用__cdecl约定,导致编译链接错误的问题。
摘要由CSDN通过智能技术生成
 

stdcall调用约定分析,以c语言为分析对象

-、编译平台

本文中C代码的编译平台为VC6.0,编译版本为Debug版本。

二、研究的C代码

int __stdcall stdcallFun(int Num1 , int Num2)

{

    if (Num1 > Num2)

        return Num1 ;

    else

      return Num2 ;

}

void main(int argc, char *argv[])

{

    int x1 , x2 , nBigger;

    x1 = 5 ;

    x2 = 6 ;

    nBigger = stdcallFun(x1,x2) ;

    return ;

}

三、利用VC调试时,查看Debug版本的汇编代码(如看不懂该部分代码可直接跳到第四点的分析部分)

stdcallFun函数

stdcallFun:

004010A0   push        ebp ;保存ebp                     

004010A1   mov        ebp,esp

004010A3   sub         esp,40h ; stdcallFun分配临时变量

004010A6   push        ebx

004010A7   push        esi

004010A8   push        edi ;保护现场

004010A9   lea         edi,[ebp-40h]

004010AC   mov         ecx,10h

004010B1   mov         eax,0CCCCCCCCh

004010B6   rep stos    dword ptr [edi]  ;初始化临时变量

004010B8   mov         eax,dword ptr [ebp+8] ;mov eax, Num1

004010BB   cmp         eax,dword ptr [ebp+0Ch] cpm Num1,Num2

004010BE   jle         stdcallFun+25h (004010c5)

004010C0   mov         eax,dword ptr [ebp+8]

004010C3   jmp         stdcallFun+28h (004010c8)

004010C5   mov         eax,dword ptr [ebp+0Ch]

004010C8   pop         edi

004010C9   pop         esi

004010CA   pop        ebx

004010CB   mov        esp,ebp

004010CD   pop         ebp

004010CE   ret         8

main函数

main:

004010EC   mov         ecx,13h

004010F1   mov         eax,0CCCCCCCCh

004010F6   rep stos       dword ptr [edi]

004010F8   mov         dword ptr [ebp-4],5   ;x1 = 5

004010FF   mov         dword ptr [ebp-8],6    ;x2 = 6

00401106   mov         eax,dword ptr [ebp-8] 

00401109   push         eax                 ;变量x2的值入栈

0040110A   mov         ecx,dword ptr [ebp-4]

0040110D   push         ecx               ;变更x1的值入栈

0040110E   call          @ILT+25(_stdcallFun@8) (0040101e)

00401113   mov         dword ptr [ebp-0Ch],eax

00401116   pop          edi

00401117   pop          esi

00401118   pop          ebx

00401119   add          esp,4Ch

0040111C   cmp         ebp,esp

0040111E   call        __chkesp (00401280) ;调试代码

00401123   mov         esp,ebp

00401125   pop         ebp

00401126   ret

四、阶段分析

1.理解stdcall参数传递规则的关键是C语言的变量内存分配规则。对于全局变量和static变量分配的内存空间为全局内存空间;对于函数的局部变量执行函数时分配,退出执行函数收回分配空间。变量的内存空间为栈(stack)。而程序执行中程序员动态审请的内存则位于全局的堆(heap)中。所以我们以下分析函数调用传递规则时,将结合栈的变化图分析。

2.阶段分析

a.main函数局部变量分配初始化

void main()

{

    int x1 , x2 , nBigger;

程序执行到此处

对应汇编代码为:

00401060   push       ebp

00401061   mov        ebp,esp

00401063   sub        esp,4Ch  ;main函数分配局部变量在stack里边分配

00401066   push       ebx

00401067   push       esi

00401068   push       edi ;保护现场

00401069   lea         edi,[ebp-4Ch]

0040106C   mov       ecx,13h

00401071   mov       eax,0CCCCCCCCh 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值