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

  • 加法:

示例:

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

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

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

如果我们稍加修改:

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

  • 乘法

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

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

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

Release版本优化后:

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

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

  • 除法

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

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

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

除以非2的幂的常量:

余数保存在edx中:

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

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

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

  • 自增

  • 表达式短路

逻辑与运算:

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

  • 条件表达式

示例:

  • 位移运算

对于有符号位移:

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

对于无符号位移:

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

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

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

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

  1. C++反汇编与逆向分析技术揭秘

    C++反汇编-继承和多重继承   学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记 一.单类继承 在父类中声明为私有的成员,子类对象无法直接访问,但是在子类对象的 ...

  2. 《C++反汇编与逆向分析技术揭秘》--算术运算和赋值

    一.加法 1.Debug下: 14: int nVarOne0 = 1 + 5 - 3 * 6;//编译时计算得到结果 00C0550E C7 45 F8 F4 FF FF FF mov dword ...

  3. 《C++反汇编与逆向分析技术揭秘》--认识启动函数,找到用户入口

    <C++反汇编与逆向分析>和<程序员的自我修养>都是以VC6的代码作为例子讲解的.这里是在vs2017下,CRT代码有些区别,但整体流程上都是初始化环境,设置参数,最后转到用户 ...

  4. 《C++反汇编与逆向分析技术揭秘》——基本数据类型的表现形式

    ---恢复内容开始--- 基本的浮点数指令 示例代码: Visual Studio 2013的反汇编代码是: 对于movss,表示移动标量单精度浮点值 将标量单精度浮点值从源操作数(第二个操作数)移到 ...

  5. 《C++反汇编与逆向分析技术揭秘》之十——构造函数

    对象生成时会自动调用构造函数.只要找到了定义对象的地方,就找到了构造函数调用的时机.不同作用域的对象的生命周期不同,如局部对象.全局对象.静态对象等的生命周期各不相同,只要知道了对象的生命周期,便可以 ...

  6. 《C++反汇编与逆向分析技术揭秘》——函数的工作原理

    各种调用方式的考察 示例: cdecl方式是调用者清空堆栈: 如果执行的是fastcall: 借助两个寄存器传递参数: 参数1和2借助局部变量来存储: 返回值 如果返回值是结构体: 返回值存放在eax ...

  7. 《C++反汇编与逆向分析技术揭秘》——流程控制语句的识别

    if...else...语句 示例: if构成多分支语句 switch 有序线性的switch: 3E82D8位置存放了一个表,标明了要跳转到的地址: 这里的每四字节都标明的是每个case块的首地址: ...

  8. 《C++反汇编与逆向分析技术揭秘》之12——继承

    识别类和类之间的关系 在父类中声明为私有的成员,虽然子类对象无法直接访问,但是在子类对象的内存结构中,父类私有的成员数据依然存在. 在没有提供构造函数的时候,系统会尝试提供默认的构造函数: 当子类中没 ...

  9. 《C++反汇编与逆向分析技术揭秘》之11——虚函数

    虚函数的机制 当类中定义有虚函数时,编译器会将该类中所有虚函数的首地址保存在一张地址表中,这张表被称为虚函数地址表.编译器还会在类中添加一个虚表指针. 举例: CVirtual类的构造函数中没有进行任 ...

随机推荐

  1. MVC 4 插件化架构简单实现

    转ASP.NET MVC 4 插件化架构简单实现-思路篇   用过和做过插件的都会了解插件的好处,园子里也有很多和讨论,但大都只些简单的加载程序集什么的,这里主要讨论的就是使用 ASP.NET MVC ...

  2. 寻找最大的k个数

    这个题目是非常经典的一个题目,解法也有很多,现在就把我已经理解的解法记录下来. 题目描述 有n个无序的数,它们各不相等,怎样选出其中的最大的k个数呢? 题目分析: 解法1: 最容易想到的就是把n个数进 ...

  3. poj2236无线网络

    这一题的大意:在救灾当中需要用网络,这堆人就用笔记本建了一个无线网,但是来,互相通信都是有距离限制的,一台电脑只能和距离他为d的电脑通信,然后一台电脑也可以通过几台电脑搭成线这样通信.然后就是输入每台 ...

  4. MongoDB学习(翻译3)

    支持的where字句(比较多,今天先写一部分) 本节介绍支持的where字句 正如前面提到的,不是所有的C#表达式都支持where子句.您可以以此文为指导,或者你可以尝试表达,看看它是否工作(如果不支 ...

  5. 简单使用JSON,通过JSON 字符串来创建对象(二)

    把 JSON 文本转换为 JavaScript 对象 JSON 最常见的用法之一,是从 web 服务器上读取 JSON 数据(作为文件或作为 HttpRequest),将 JSON 数据转换为 Jav ...

  6. S2SH整合

    Struts2.Spring.Hibernate三大框架在一个项目中的具体职责分配如下: 三大框架整合,导入各个框架和整合所需的包(本项目采用的是Struts2.3+spring3.0+hiberna ...

  7. Reeder Web版

    Reeder Web版 访Reeder界面效果 一直很欣赏触控手势的代码实现,所以最近折腾了个Javascript触控手势库--JTouch,效果还有诸多不完善之处,苦于硬件设备不完善,针对ie10的 ...

  8. CDM业务单据,表体单价列赋值所需要注意的问题

    需要将销售退回入库单据的单价自动去商品资料里的零售价值. 写了检索方案,然后 select * .............    spkfk.lshj as dj.........  ,但是发现定价依 ...

  9. MacOSX中使用NSWindow创建背景透明的窗体

    1.Windows 在window上创建异形窗体必须要使用WS_EX_LAYERED样式,再调用SetLayeredWindowAttributes设置透明度或者透明颜色属性.用updatelayer ...

  10. JBPM之JPdl小叙

    JPdl:jbpm流程定义文件,下面是一个简单的流程定义文件: <?xml version="1.0" encoding="UTF-8"?> < ...