《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

---恢复内容开始---

  • 加法:

 示例:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

 

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

常量相加,则在编译期间就计算出两个常量相加后的结果,直接将这个结果参与运算,减少了运行期的计算。当有变量参与运算时,会先取出内存中的数据,放入通用寄存器中,再通过加法指令来完成计算过程得到结果。

如果开启O2选项,则是考虑效率优先,编译出来的汇编代码会有很大的变化:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

如果使用Release版本开启O2选项后,再查看反汇编,则略过很多无用的步骤,直接给printf压入一个常量作为参数:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

如果我们稍加修改:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

用命令行参数的个数argc去初始化两个变量,那么由于argc的个数在编译期间无法确定,所以程序中的变量就不会被常量替换掉:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

  • 乘法

 乘法运算对应的汇编指令有有符号imul和mul两种。由于乘法指令的执行周期较长,在编译过程中,编译器会先尝试将乘法转换成加法,或使用移位等周期较短的指令。当它们都不可转换时,才会使用乘法指令。

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

这里Debug版本的代码,更侧重调试,如果这个乘数常量不是2的幂,那么就会使用imul指令进行乘法。当常量值为2的幂时,编译器会采用执行周期短的左移运算来代替执行周期长的乘法指令。当乘数和被乘数同时都是未知变量时,则无法套用优化方案。这时编译器不会优化处理,将直接使用乘法指令完成计算。

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

乘法运算与加法运算相结合采用LEA指令来处理。

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

Release版本优化后:

乘以15变成乘以16再减去自身:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

两个未知变量相乘,无法优化,依然使用imul指令:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

  • 除法

除法运算对应的汇编指令分为有符号idiv和无符号div

 《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

先用cdq命令扩展高位,然后直接使用idiv有符号除法和无符号div去进行计算。除法运算的计算周期较长,效率也较低,所以编译器想尽办法用其它运算指令代替除法指令:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

除以2采用的是右移。在扩充完高位之后,要自身减去扩充位,然后再右移一位:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

除以非2的幂的常量:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

余数保存在edx中:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

切换到Release版本,各类型的除法会进行一定的优化,比如除以非2的幂的时候:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

 这里是除数为负的2的幂的情况:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

除数为负的非2的幂的情况:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

  • 自增

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

  • 表达式短路

 逻辑与运算:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

逻辑或运算,等于1直接满足条件return:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

  • 条件表达式

 示例:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

  • 位移运算

对于有符号位移:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

有符号数右移使用sar指令,保留符号位:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

对于无符号位移:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

使用shr指令,右移高位补0:

《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

 有符号数和无符号数的左移都是一样的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

---恢复内容结束---

原文链接: https://www.cnblogs.com/predator-wang/p/6283460.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/247635

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月14日 上午2:23
下一篇 2023年2月14日 上午2:23

相关推荐