《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程
---恢复内容开始---
- 加法:
示例:


常量相加,则在编译期间就计算出两个常量相加后的结果,直接将这个结果参与运算,减少了运行期的计算。当有变量参与运算时,会先取出内存中的数据,放入通用寄存器中,再通过加法指令来完成计算过程得到结果。
如果开启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++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程的更多相关文章
- C++反汇编与逆向分析技术揭秘
C++反汇编-继承和多重继承 学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记 一.单类继承 在父类中声明为私有的成员,子类对象无法直接访问,但是在子类对象的 ...
- 《C++反汇编与逆向分析技术揭秘》--算术运算和赋值
一.加法 1.Debug下: 14: int nVarOne0 = 1 + 5 - 3 * 6;//编译时计算得到结果 00C0550E C7 45 F8 F4 FF FF FF mov dword ...
- 《C++反汇编与逆向分析技术揭秘》--认识启动函数,找到用户入口
<C++反汇编与逆向分析>和<程序员的自我修养>都是以VC6的代码作为例子讲解的.这里是在vs2017下,CRT代码有些区别,但整体流程上都是初始化环境,设置参数,最后转到用户 ...
- 《C++反汇编与逆向分析技术揭秘》——基本数据类型的表现形式
---恢复内容开始--- 基本的浮点数指令 示例代码: Visual Studio 2013的反汇编代码是: 对于movss,表示移动标量单精度浮点值 将标量单精度浮点值从源操作数(第二个操作数)移到 ...
- 《C++反汇编与逆向分析技术揭秘》之十——构造函数
对象生成时会自动调用构造函数.只要找到了定义对象的地方,就找到了构造函数调用的时机.不同作用域的对象的生命周期不同,如局部对象.全局对象.静态对象等的生命周期各不相同,只要知道了对象的生命周期,便可以 ...
- 《C++反汇编与逆向分析技术揭秘》——函数的工作原理
各种调用方式的考察 示例: cdecl方式是调用者清空堆栈: 如果执行的是fastcall: 借助两个寄存器传递参数: 参数1和2借助局部变量来存储: 返回值 如果返回值是结构体: 返回值存放在eax ...
- 《C++反汇编与逆向分析技术揭秘》——流程控制语句的识别
if...else...语句 示例: if构成多分支语句 switch 有序线性的switch: 3E82D8位置存放了一个表,标明了要跳转到的地址: 这里的每四字节都标明的是每个case块的首地址: ...
- 《C++反汇编与逆向分析技术揭秘》之12——继承
识别类和类之间的关系 在父类中声明为私有的成员,虽然子类对象无法直接访问,但是在子类对象的内存结构中,父类私有的成员数据依然存在. 在没有提供构造函数的时候,系统会尝试提供默认的构造函数: 当子类中没 ...
- 《C++反汇编与逆向分析技术揭秘》之11——虚函数
虚函数的机制 当类中定义有虚函数时,编译器会将该类中所有虚函数的首地址保存在一张地址表中,这张表被称为虚函数地址表.编译器还会在类中添加一个虚表指针. 举例: CVirtual类的构造函数中没有进行任 ...
随机推荐
- [转]Metasploit的meterpreter黑客脚本列表
原文地址: 摘要: Metasploit的框架是一个令人难以置信的黑客攻击和渗透测试工具,每一个黑客称职的应该是熟悉和有能力的. 在上一篇文章中,我提供了你的 meterpreter 命令列表.这些命 ...
- [置顶] 从引爆点的角度看360随身wifi的发展
从引爆点的角度看360随身wifi的发展 不到一个月的时间,随身wifi预定量就数百万.它的引爆点在哪里,为什么相同的产品这么多它却能火起来,通过对随身wifi的了解和我知识层面分析,主要是因为随身w ...
- asp.net MVC实现文章的“上一篇下一篇”
由于这个东西的原理没有什么难的(只是实现的时候有少量的坑),故直接上代码以便查阅.另:本文给出的Action附送了点击量统计. public ActionResult SingleNews(int? ...
- js框架漫谈
现在实际项目中可供选择的javascript框架很多,热门的有jquery,dojo,mootools,ext等.这些框架按照不同的标准有不同的分类方法,比如按照扩展方式便可分为prototype式的 ...
- jquery选择器之内容过滤选择器
先写出DOM元素的HTML结构: <style type="text/css"> /*高亮显示*/ .highlight{ background-color: gray ...
- WP中一些耗时的东西
MediaPlayer.GameHasControl 耗时1.5ms MediaPlayer.State 耗时0.4ms 上面两个原本放在游戏的update中,后来注释掉发现其它的游戏逻辑只要0.2m ...
- CSS:CSS学习总结
CSS:CSS学习总结 背景 CSS是一种声明式的语言,学好CSS的难度甚至大于学好一门服务器语言(我个人的感觉),这周在学习CSS,就记录一下学习经验. 1.规则声明顺序 因为CSS的样式具备层叠性 ...
- 分享一个自己写的MVC+EF “增删改查” 无刷新分页程序
分享一个自己写的MVC+EF “增删改查” 无刷新分页程序 一.项目之前得添加几个组件artDialog.MVCPager.kindeditor-4.0.先上几个效果图. 1.首先建立一个数 ...
- JS左侧菜单-04
<script language="javascript" type="text/javascript"> function HideShow() ...
- Use weechat (IRC client) on OS X. MacBook Pro
Weechat is a console IRC client. It is opensource and very easy to use. I use weechat in my Linux PC ...