VC6对函数返回过程的优化(上)

写了一天的计划,轻松一下脑筋,看看VC++6.0是怎么优化函数的返回值的过程。创建一个叫test的控制台项目。编译然后把反汇编的选项打开。

先作一个加法运算: c = a + b
1:    // test.cpp : Defines the entry point for the console application.
2:    //
3:
4:    #include "stdafx.h"
5:
6:    int test( int a, int b);
7:
8:
9:    int main(int argc, char* argv[])
10:   {
0040D3B0   push        ebp
0040D3B1   mov         ebp,esp
0040D3B3   sub         esp,4Ch
0040D3B6   push        ebx
0040D3B7   push        esi
0040D3B8   push        edi
0040D3B9   lea         edi,[ebp-4Ch]
0040D3BC   mov         ecx,13h
0040D3C1   mov         eax,0CCCCCCCCh
0040D3C6   rep stos    dword ptr [edi]

11:       int a, b, c;
12:
13:       a = 0x11;
0040D3C8   mov         dword ptr [ebp-4],11h
14:       b = 0x30;
0040D3CF   mov         dword ptr [ebp-8],30h
15:
16:       c = test( a, b);
0040D3D6   mov         eax,dword ptr [ebp-8] ; 取变量b的值
0040D3D9   push        eax                   ; 压栈,变量是从右到左压栈
0040D3DA   mov         ecx,dword ptr [ebp-4] ; 取变量b的值
0040D3DD   push        ecx                   ; 压栈
0040D3DE   call        @ILT+0(test) (00401005)
0040D3E3   add         esp,8                 ; 恢复栈
0040D3E6   mov         dword ptr [ebp-0Ch],eax

17:
18:       return 0;
0040D3E9   xor         eax,eax
19:   }
0040D3EB   pop         edi
0040D3EC   pop         esi
0040D3ED   pop         ebx
0040D3EE   add         esp,4Ch
0040D3F1   cmp         ebp,esp
0040D3F3   call        __chkesp (0040d400)
0040D3F8   mov         esp,ebp
0040D3FA   pop         ebp
0040D3FB   ret

20:
21:
22:   int test( int a, int b)
23:   {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,44h           ;
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-44h]
0040105C   mov         ecx,11h
00401061   mov         eax,0CCCCCCCCh  
00401066   rep stos    dword ptr [edi]   ;初始化局部变量空间

24:       int c;
25:       c = a + b;
00401068   mov         eax,dword ptr [ebp+8]
0040106B   add         eax,dword ptr [ebp+0Ch]
0040106E   mov         dword ptr [ebp-4],eax

26:       return c;
00401071   mov         eax,dword ptr [ebp-4]
27:   }
00401074   pop         edi
00401075   pop         esi
00401076   pop         ebx
00401077   mov         esp,ebp
00401079   pop         ebp
0040107A   ret

26行里面,函数的返回值被放到了EAX里面。好奇的人一定要问,如果返回值是一个结构怎么办?下一个,我们让返回值是一个复数结构(长度是两个32bits)

1:    // test.cpp : Defines the entry point for the console application.
2:    //
3:
4:    #include "stdafx.h"
5:
6:    struct complex{
7:        int i; //real part
8:        int j; //virtual part
9:    };
10:
11:   complex test( int a, int b);
12:
13:
14:   int main(int argc, char* argv[])
15:   {

0040D440   push        ebp
0040D441   mov         ebp,esp
0040D443   sub         esp,58h
0040D446   push        ebx
0040D447   push        esi
0040D448   push        edi
0040D449   lea         edi,[ebp-58h]
0040D44C   mov         ecx,16h
0040D451   mov         eax,0CCCCCCCCh
0040D456   rep stos    dword ptr [edi]

16:       int a, b;
17:       struct complex c;
18:
19:       a = 0x11;
0040D458   mov         dword ptr [ebp-4],11h
20:       b = 0x30;
0040D45F   mov         dword ptr [ebp-8],30h
21:
22:       c = test( a, b);
0040D466   mov         eax,dword ptr [ebp-8]
0040D469   push        eax
0040D46A   mov         ecx,dword ptr [ebp-4]
0040D46D   push        ecx
0040D46E   call        @ILT+10(test) (0040100f)
0040D473   add         esp,8
0040D476   mov         dword ptr [ebp-18h],eax
0040D479   mov         dword ptr [ebp-14h],edx
0040D47C   mov         edx,dword ptr [ebp-18h]
0040D47F   mov         dword ptr [ebp-10h],edx
0040D482   mov         eax,dword ptr [ebp-14h]
0040D485   mov         dword ptr [ebp-0Ch],eax

23:
24:       return 0;
0040D488   xor         eax,eax
25:   }
0040D48A   pop         edi
0040D48B   pop         esi
0040D48C   pop         ebx
0040D48D   add         esp,58h
0040D490   cmp         ebp,esp
0040D492   call        __chkesp (0040d400)
0040D497   mov         esp,ebp
0040D499   pop         ebp
0040D49A   ret

28:   struct complex test( int a, int b)
29:   {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,48h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-48h]
0040105C   mov         ecx,12h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]

30:       struct complex c;
31:       c.i = a;
00401068   mov         eax,dword ptr [ebp+8]
0040106B   mov         dword ptr [ebp-8],eax

32:       c.j = b;
0040106E   mov         ecx,dword ptr [ebp+0Ch]
00401071   mov         dword ptr [ebp-4],ecx

33:
34:       return c;
00401074   mov         eax,dword ptr [ebp-8]
00401077   mov         edx,dword ptr [ebp-4]

35:   }
0040107A   pop         edi
0040107B   pop         esi
0040107C   pop         ebx
0040107D   mov         esp,ebp
0040107F   pop         ebp
00401080   ret

注意看34行,编译器够聪明,用EAXEDX来返回复数c的实部和虚部。嘿嘿,我就不相信你x86CISC处理器的寄存器能多过RISC处理器,返回值是更多个32bits又到哪里去找那么多寄存器呢?电动力学的四个方程都可以把变量表达成(x,y,z,t)这样的向量,我让子函数返回这样一个向量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值