鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 编程语言开发 > c语言 > >

抠门的Release版本对代码动了哪些手脚

来源:互联网 作者:佚名 时间:2013-03-28 13:39
Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。 Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 相信不少朋友用C++开发时,用debug版本可以运行,但用R

Debug 通常称为调试版本,香港服务器,它包含调试信息,并且不作任何优化,便于程序员调试程序。

Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。

     相信不少朋友用C++开发时,用debug版本可以运行,但用Release版本就不行了,或者倒过来。根本原因就是Release版本优化的问题,如果用Release版本调试会看到“面目全非”的反汇编代码,很多地方与源码对不上,而debug版本没有做任何优化,代码与汇编能一一对上。

本人菜鸟抛砖引玉举几个例子,服务器空间,看看Release对代码做了什么手脚,下面只贴上Release版本代码,读者可以自己运行看看Debug版本代码,欢迎补充!

/*********************************

运行和调试环境:VS2010 + win 7

程序类型:控制台

配置:默认

/*********************************

1, 变量优化------国家穷,能省就省

示例:

#include main(){ int intA; int intB; char ch[5]={0}; char *pCh=ch; pCh+=11111;//数组越界 *pCh=;//非法内存写入数据 intA=100; scanf(,&intB); printf(,intA); return; }

     上面的代码在两个版本中编译通过,但在Release中可以运行,但在Debug中运行出错。先提一个问题,Release中有多少个变量会分配栈空间

--------------Realease版本汇篇----------------

#include main(){ 002A1000 push ebp 002A1001 mov ebp,esp 002A1003 sub esp, 002A1006 mov eax,dword ptr [___security_cookie (2A3000h)] 002A100B xor eax,ebp 002A100D mov dword ptr [ebp-intA; intB; *pCh=ch; //优化掉 pCh+=11111; //优化掉 *pCh=; //优化掉 intA=100; //优化掉 scanf(,&intB); 002A1010 lea eax,[ebp-8] 002A1013 push eax //可以看出为intB分分配4字节空间 002A1014 push offset (2A20F4h) 002A1019 call dword ptr [__imp__scanf (2A20A4h)] printf(,intA); 002A101F push 64h //立即数,intA被优化掉了 002A1021 push offset (2A20F4h) 002A1026 call dword ptr [__imp__printf (2A209Ch)] return; }

相信熟悉汇编的朋友一看就知道只有intB分配栈空间。intA即使有运算操作,也优化掉了。ch[5],*pCh因为优化,所以不存在数组越界访问的问题。

Release认为国家穷能省就省,所以把一个函数看成一个黑盒,在对外面的输入输出不影响的情况下,能省就省,越简单越好。

2, if语句的优化变换----变形金刚,变身只为更强大

示例:

#include main(){ int intA; int intB; scanf(,&intB); if (intB) { intA=13; }else intA=16; printf(,intA); }

     if语句中判断真假因为依赖intB,所以intA的值不能确定,因而printf("%d",intA)的输出在编译时也不能确定。我想,这样编译器会给intA一个栈空间吧?结果我错了,编译器很扪门,把intA优化掉了。下面看看编译器怎么做的。假定这里输入5,即让intB=5。

 ----------------- Realease版本汇编--------------------

#include main(){ 01361000 push ebp 01361001 mov ebp,esp 01361003 push ecx int intA; int intB; scanf(,&intB); push eax (13620F4h) 0136100D call dword ptr [__imp__scanf (13620A4h)] mov eax,dword ptr [intB] neg eax sbb eax,eax//带位相减。由于CF=1,所以eax=0xFFFFFFFF 0136101A and eax,FFFFFFFDh //与运算后eax=0xFFFFFFFD 0136101D add eax,10h //溢出,结果为eax=0xD(十进制13),所以说0xFFFFFFFD相当于-3 { intA=13; //ß-----------13 }else intA=16;// printf(,intA); 01361020 push eax (13620F4h) 01361026 call dword ptr [__imp__printf (136209Ch)] 0136102C add esp,10h }

     由上可以看出If的优化后的语句效率很高,运算基本上都是在寄存器上进行的,没有cmp,jmp语句,没有分配额外的栈空间,服务器空间,寻址用立即数。

3, 函数合并----联合起来为了利益最大化

示例:

#include fun(int a,char ch[]){ printf(,a,ch); } void main(){ int intA; ; intA=15; fun(intA,ch); }

当然在main中intA被优化掉了,函数传递用立即数,但数组ch[ ]没有被优化掉。这里有两个函数,所以在反汇编中应该能看到call fun这样的语句吧?答案是否定的。

 ----------------- Realease版本汇编--------------------

网友评论
<