你的位置:首页 > 软件开发 > ASP.net > C++反汇编学习笔记(五)编译器(VS2013)常用的几个优化技巧(1)

C++反汇编学习笔记(五)编译器(VS2013)常用的几个优化技巧(1)

发布时间:2015-04-09 16:00:28
编译器的工作过程中可以分为几个阶段:预处理-》词法分析-》语法分析-》语义分析-》中间代码生成-》目标代码生成。其中,优化的机会一般存在于中间代码生成或目标代码生成这两个阶段。尤其是在中间代码生成阶段所做的优化,这类优化不具备设备相关性,在不同的硬件环境中都能通用。debug下, ...

编译器的工作过程中可以分为几个阶段:预处理-》词法分析-》语法分析-》语义分析-》中间代码生成-》目标代码生成。其中,优化的机会一般存在于中间代码生成或目标代码生成这两个阶段。尤其是在中间代码生成阶段所做的优化,这类优化不具备设备相关性,在不同的硬件环境中都能通用。

debug下,为了调试方便,保持原码与反汇编代码的一一对应,只是进行了很少的优化。

常见的与设备无关的优化方案有以下几种:

1、  常量折叠

  当计算公式中出现多个常量进行计算,且编译器可以在编译期间计算出结果时,这样原码中所有的常量计算都将被计算结果代替

  如:x=1+2结果必然是3,因此在编译期间直接生成x=3,没必要产生加法指令。

2、  常量传播

  如果在程序的逻辑中,声明的变量没有修改过,而且上下文中不存在针对此变量的取地址和间接访问操作,那么这个变量就等价与常量,编译器就认为可以删除该变量,直接用常量代替。使用常量的好处是可以生成立即数寻址的目标代码,减少了内存的访问次数。

  如:x=1+2;y=x+3;因为x已经计算出结果为3,所以x被常量3代替,这里直接生成y=6。

3、  公共表达式

  如:x=i*2;y=i*2;这时i*2被称为公共表达式,可归并为一个:x=i*2;y=x;得到x的值之后直接赋值给y,而不会再进行一次i*2的计算。

4、  复写传播

  类似常量传播,但目标变为了变量

  如x=a;.......y=x+c;如果在省略号表示的代码中没有修改变量x的值,则可以直接用变量a代替x,得到y=a+c。

5、  剪支优化

  如:if(1>2),因为条件永远为假,所以整个if代码块没有存在的必要,因此不会产生指令。

6、  顺序语句代替分支

  如if(2>1)....else.......在编译期间就可以计算出条件的真假,因此直接生成将被执行代码块的指令,优化掉判断和不可达的代码指令。

7、  数学变换

  像x=a+0;x=a-0;x=a*1;x=a/1都是代数恒等式,不会产生运算指令,直接生成x=a;

  x=a*y+b*y;等价于x=(a+b)*y,所以只需一次加法一次乘法即可。

8、  代码外提 

  这类优化一般存在于循环中

  如:while(x>y/2);如果循环体中没有修改y的值,那么没必要每次循环判定条件时,都进行一次y/2的运算,因此优化为:t=y/2;while(x>t);

 

第一格是C++原码,第二格是debug下反汇编代码,第三格是release反汇编下代码,重点看。

代码中的所有输入输出句都是为了防止变量被优化掉,没有其他意义。

 

C++反汇编学习笔记(五)编译器(VS2013)常用的几个优化技巧(1)C++反汇编学习笔记(五)编译器(VS2013)常用的几个优化技巧(1)
#include <iostream>using namespace std;int main(){//=======================================常量折叠与常量传播  int a1;  a1 = 1 + 1;  cout << a1 << endl;//=======================================减少变量  int x1, y1, m1, n1;  cin >> m1 >> n1;  x1 = m1 * 2;  y1 = n1 * 2;  if (x1 > y1)    cout <<"TRUE"<< endl;//=======================================公共表达式  int x2, y2, m2;  cin >> m2 ;  x2 = m2 * 2;  y2 = m2 * 2;  cout << x2 << y2 << endl;  cin >> x2 >> y2;//=======================================复写传播  int x3, y3, a,c;  cin >> a>>c;  x3 = a;  y3 = x3 + c;  cout << x3 << y3 << endl;  cin >> x3 >> y3;//=======================================剪去不可达分支(剪支优化)  if (1 > 2)    cout << "TRUE" << endl;//=======================================顺序语句代替分支  int a2;  cin >> a2;  a2 == 5 ?a2= 6 :a2= 7;  cout << a2<< endl;//=======================================强度削弱  int x4, y4, a3;  cin >> a3 ;  x4 = a3*2;  y4 = a3 / 4;  cout << x4 << y4;//=======================================数学变换  int x5, y5, a4, b4;  cin >> a4 >> b4;  x5 = a4 * 1;  y5 = a4*x5 + b4*x5;  cout << x5 << y5 << endl;//=======================================代码外提  int x6, y6;  cin >> x6 >> y6;  while (x6 < y6 / 2)  {    cout << x6 << endl;    x6++;  }//===============================================  system("pause");  return 0;}

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:C++反汇编学习笔记(五)编译器(VS2013)常用的几个优化技巧(1)

关键词:

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录