您的位置:首页 > 其它

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

2010-03-06 22:35 375 查看
写了一天的计划,轻松一下脑筋,看看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行,编译器够聪明,用EAX和EDX来返回复数c的实部和虚部。嘿嘿,我就不相信你x86的CISC处理器的寄存器能多过RISC处理器,返回值是更多个32bits又到哪里去找那么多寄存器呢?电动力学的四个方程都可以把变量表达成(x,y,z,t)这样的向量,我让子函数返回这样一个向量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: