《C++反汇编与逆向分析技术揭秘》笔记-第4章观察各种表达式的求值过程(下)

4.2关系运算和逻辑运算
1.条件跳转指令表如下。通常情况下,这些条件跳转指令都与cmp和test匹配出现,但条件跳转指令检查的是标记位。因此,在有修改标记位的代码处,也可以根据需要使用条件跳转指令修改程序流程。



2.利用表达式短路可以实现用递归方式计算累加和,代码如下。


3.条件表达式,表达式1?表达式2:表达式3
当表达式1为常量值时,编译器会在编译期间得到答案,不会存在条件表达式。
release版本如下。分析:1.可以使用setne、setle、setge、cmove、cmovg、cmovl等指令进行无分支优化。
setne:如果比较的结果不相等,将指定的目标寄存器设为1;否则将其设为0。
setle:如果比较的结果小于等于,则将指定的目标寄存器设为1;否则将其设为0。
setge:如果比较的结果大于等于,则将指定的目标寄存器设为1;否则将其设为0。
cmove:如果比较的结果相等,则将源操作数的值移动到目标操作数中;否则不执行任何操作。
cmovg:如果比较的结果大于,则将源操作数的值移动到目标操作数中;否则不执行任何操作。
cmovl:如果比较的结果小于,则将源操作数的值移动到目标操作数中;否则不执行任何操作。
2.当表达式2或表达式3有变量表达式时,会转换成分支结构,即不优化。但在复杂的条件表达式中,使用分支通常比使用条件传送的性能更高。

4.3位运算:二进制数据的运算
<<:左移运算,最高位左移到CF中,最低位零。(对应汇编指令shl)
>>:右移运算,最高位不变,最低位右移到CF中。(对应汇编指令sar,shr,无符号数不需要符号位所以直接使用shr将最高位补0)
|:位或运算,在两个数的相同位上,只要有一个为1,结果为1。(对应汇编指令or)
&:位与运算,在两个数的相同位上,同时为1时,结果为1。(对应汇编指令and)
^:异或运算,在两个数的相同位上,不同时,结果为1。(对应汇编指令xor)
~:取反运算,将操作数每一位的1变0,0变1。(对应汇编指令not)
由于大多数位运算会导致数据信息的丢失(取反和异或可以反推除外)因此,在知道原算法的前提下,使用逆转算法是无法计算出原数据的。如x&0结果为0,而根据结果,是不可以逆推x的值。


4.4编译器使用的优化技巧
1.代码优化一般有4个方向:执行速度优化、内存存储空间优化、磁盘存储空间优化、编译时间优化。常见的是以执行速度为主的优化。
2.编译器工作过程分为几个阶段:预处理-词法分析-语法分析-语义分析-中间代码生成-目标代码生成。优化一般存于后两个阶段,尤其在中间代码生成阶段所作的优化不具备设备相关性,在不同的硬件环境中都能通用。
3.常见的中间代码生成阶段的优化方案:
(1)常量折叠,如x=1+2;直接生成x=3;
(2)常量传播,如接上例,y=x+3;直接生成y=6;
(3)减少变量,如x=i*2;y=j*2;if(x>y){...} 如果其后再也没有引用x、y,直接生成if(i>j){...}
(4)公共表达式,如x=i*2;y=i*2;直接生成x=i*2;y=x;
(5)复写传播,,类似于常量传播,但是目标变成了变量。如x=a;y=x+c;直接生成y=a+c;
(6)剪去不可达分支(剪支优化),如if(1>2){...} 直接删掉。
(7)顺序语句代替分支,如条件表达式的优化。
(8)强度削弱,如乘除法的优化,用加法或者移位代替乘法,用乘法或者移位代替除法。
(9)数学变换,如x=a*y+b*y;直接生成x=(a+b)*y;
(10)代码外提,一般存于循环中,如while(x>y/2){...} 如果循环体内没有修改y值,直接生成 t=y/2;while(x>t){...}
4.目标代码生成阶段的优化方案:
(1)流水线优化,02选项生成的代码会考虑流水线优化(前提条件是不影响计算结果)。
注意事项<1>指令相关性,如顺序安排的两条指令,都需要访问并设置edx,会导致寄存器争用,影响并行效率,应尽量避免。<2>地址相关性,如顺序安排的两条指令,第一条指令需要计算并回写到[00401234],而第二条指令也需要访问[00401234],会导致内存地址争用,影响并行效率,应尽量避免。
(2)分支优化,在流水线工作模式下,如果遇到分支结构,就可以利用分支目标缓冲器预测并读取指令的目标地址。因此,在编写多重循环时应该把大循环放到内层,这样可以增加分支预测的准确度。如for(int i=0;i<10;i++)//下面每次循环会预测成功9999次,预测失败1次(第一次没有预测),这样的过程重复10次 for(int j=0;j<10000;j++)a[i][j]++; 又如for(int j=0;j<10000;j++)//下面每次循环会预测成功9次,预测失败1次(第一次没有预测),这样的过程重复10000次for(int i=0;i<10;i++)a[i][j]++;
分支优化主要体现在减少分支结构上,使用顺序结构代替分支结构,使用查表法代替分支结构。
3.高速缓存(cache)优化,优点:数据对齐、数据集中、减少体积。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值