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)这样的向量,我让子函数返回这样一个向量。
先作一个加法运算: 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)这样的向量,我让子函数返回这样一个向量。
相关文章推荐
- VC6对函数返回过程的优化(下)
- 【Oracle 函数索引】一次数据库的优化过程
- 数据库的几个问题存储过程触发器函数创建以及sql优化
- oracle调用存储过程和函数返回结果集
- Oracle中过程/函数返回结果集
- VC对函数调用的一个优化.
- Oracle中函数/过程返回结果集的几种方式
- 与端口冲突有关的一个低概率bug的定位过程(这次不是360的错啊)---浅谈bind()函数返回失败
- Oracle中函数/过程返回结果集的几种方式
- IBatis调用ORACLE的存储过程、函数的返回结果集例子
- Oracle中函数/过程返回结果集的几种方式
- 【Oracle 函数索引】一次数据库的优化过程
- c++(函数返回值的及其优化)
- 返回数据库数据的存储过程函数(5个参数)(SQL Server)
- java jdbc调用oracle的函数或过程返回SQL语句查询的结果集
- 过程抽象和返回一个值的函数(例子代码)
- 最完整的:JAVA调用ORACLE的存储过程、函数的返回结果集例子
- Delphi的函数及过程且参数返回数据
- VC:返回指向函数的指针
- Oracle 在函数或存储过程中执行一条插入语句并返回主键ID值