有符号数溢出:

void BreakFor()
{
for (int i = 1; i > 0; i++)
{
printf("%d \r\n", i);
}
}

上面的程序并不是死循环,当有符号数增加到最大整数后,继续加一会进位修改符号位,从而成为负数。


自增、自减

98:     int nVarOne = argc;
012665EE 8B 45 08 mov eax,dword ptr [argc]
012665F1 89 45 F8 mov dword ptr [nVarOne],eax
99: int nVarTwo = argc;
012665F4 8B 45 08 mov eax,dword ptr [argc]
012665F7 89 45 EC mov dword ptr [nVarTwo],eax
100: nVarTwo = 5 + (nVarOne++);
012665FA 8B 45 F8 mov eax,dword ptr [nVarOne]
012665FD 83 C0 05 add eax,5
01266600 89 45 EC mov dword ptr [nVarTwo],eax
01266603 8B 4D F8 mov ecx,dword ptr [nVarOne]
01266606 83 C1 01 add ecx,1 //后缀自增,在语句结束后加一
01266609 89 4D F8 mov dword ptr [nVarOne],ecx
101: nVarTwo = 5 + (++nVarOne);
0126660C 8B 45 F8 mov eax,dword ptr [nVarOne]
0126660F 83 C0 01 add eax,1 //前缀自增,先自增
01266612 89 45 F8 mov dword ptr [nVarOne],eax
01266615 8B 4D F8 mov ecx,dword ptr [nVarOne]
01266618 83 C1 05 add ecx,5
0126661B 89 4D EC mov dword ptr [nVarTwo],ecx
102:
103: nVarOne = 5 + (nVarTwo--);
0126661E 8B 45 EC mov eax,dword ptr [nVarTwo]
01266621 83 C0 05 add eax,5
01266624 89 45 F8 mov dword ptr [nVarOne],eax
01266627 8B 4D EC mov ecx,dword ptr [nVarTwo]
0126662A 83 E9 01 sub ecx,1
0126662D 89 4D EC mov dword ptr [nVarTwo],ecx
104: nVarOne = 5 + (--nVarTwo);
01266630 8B 45 EC mov eax,dword ptr [nVarTwo]
01266633 83 E8 01 sub eax,1
01266636 89 45 EC mov dword ptr [nVarTwo],eax
01266639 8B 4D EC mov ecx,dword ptr [nVarTwo]
0126663C 83 C1 05 add ecx,5
0126663F 89 4D F8 mov dword ptr [nVarOne],ecx
105: }

表达式截断:

124:     (nNumber == 0) || (nNumber += Accumulation(nNumber - 1));
0126650E 83 7D 08 00 cmp dword ptr [nNumber],0
01266512 74 15 je Accumulation+39h (01266529h) //前面为零,截断表达式,直接跳转
01266514 8B 45 08 mov eax,dword ptr [nNumber]
01266517 83 E8 01 sub eax,1
0126651A 50 push eax
0126651B E8 8B B4 FE FF call Accumulation (012519ABh) //
01266520 83 C4 04 add esp,4
01266523 03 45 08 add eax,dword ptr [nNumber]
01266526 89 45 08 mov dword ptr [nNumber],eax
125: return nNumber;
01266529 8B 45 08 mov eax,dword ptr [nNumber]
126: }

条件表达式:

  • 方案1:表达式1为简单比较,而表达式2和表达3两者的差值等于1;

return argc == 5 ? 5 : 6;

00E44BB6      | 8B7D 08            | mov edi,dword ptr ss:[ebp+0x8]  |
00E44BB9 | 33C0 | xor eax,eax |
00E44BBB | 83FF 05 | cmp edi,0x5 |
00E44BBE | 0F95C0 | setne al |//差值为一,用到setne,取得ZF值后,取反,再放到AL中,即不等时置AL为1
00E44BC1 | 83C0 05 | add eax,0x5 |
  • 方案2:表达式1为简单比较,而表达式2和表达式3两者的差值大于1;

return argc == 5 ? 4 : 10;

00E44BCF      | BE 0A000000        | mov esi,0xA                     |
00E44BD4 | 83FF 05 | cmp edi,0x5 |
00E44BD7 | 8BC6 | mov eax,esi | 00E44BD9 | BB 04000000 | mov ebx,0x4 |
00E44BDE | 0F44C3 | cmove eax,ebx |//相等的时候用ebx-->4代替eax-->10

vc6.0下

  • 方案3:表达式2和表达式3两者的差值大于1;

return argc >= 8 ? 4 : 10;

00E44BEC      | 83FF 08            | cmp edi,0x8                     |
00E44BEF | 8BC6 | mov eax,esi | esi-->1000E44BF1 | 0F4DC3 | cmovge eax,ebx |//大于等于时,用ebx-->4代替eax-->10

在vc6.0下

 

  • 方案4:表达式2和表达式3有一个为变量,于是无优化。

位运算:

141:     unsigned int nVar = argc;
0126668E 8B 45 08 mov eax,dword ptr [argc]
01266691 89 45 F8 mov dword ptr [nVar],eax
142: nVar <<= 3;
01266694 8B 45 F8 mov eax,dword ptr [nVar]
01266697 C1 E0 03 shl eax,3 //无符号数<< 使用shl 逻辑左移
0126669A 89 45 F8 mov dword ptr [nVar],eax
143: nVar >>= 5;
0126669D 8B 45 F8 mov eax,dword ptr [nVar]
012666A0 C1 E8 05 shr eax,5 //无符号数>> 使用shr 逻辑右移
012666A3 89 45 F8 mov dword ptr [nVar],eax
144:
145: argc = argc << 3;
012666A6 8B 45 08 mov eax,dword ptr [argc]
144:
145: argc = argc << 3;
012666A9 C1 E0 03 shl eax,3
012666AC 89 45 08 mov dword ptr [argc],eax
146: argc = argc >> 5;
012666AF 8B 45 08 mov eax,dword ptr [argc]
012666B2 C1 F8 05 sar eax,5 //有符号数>> 使用sar 算术右移
012666B5 89 45 08 mov dword ptr [argc],eax
147: argc = argc | 0xFFFF0000;
012666B8 8B 45 08 mov eax,dword ptr [argc]
012666BB 0D 00 00 FF FF or eax,0FFFF0000h
012666C0 89 45 08 mov dword ptr [argc],eax
148: argc = argc & 0x0000FFFF;
012666C3 8B 45 08 mov eax,dword ptr [argc]
012666C6 25 FF FF 00 00 and eax,0FFFFh
012666CB 89 45 08 mov dword ptr [argc],eax
149: argc = argc ^ 0xFFFF0000;
012666CE 8B 45 08 mov eax,dword ptr [argc]
012666D1 35 00 00 FF FF xor eax,0FFFF0000h
012666D6 89 45 08 mov dword ptr [argc],eax
150: argc = ~argc;
012666D9 8B 45 08 mov eax,dword ptr [argc]
012666DC F7 D0 not eax
012666DE 89 45 08 mov dword ptr [argc],eax
151:
152: return argc;
012666E1 8B 45 08 mov eax,dword ptr [argc]

c++ 反汇编 表达式的更多相关文章

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

    ---恢复内容开始--- 加法: 示例: 常量相加,则在编译期间就计算出两个常量相加后的结果,直接将这个结果参与运算,减少了运行期的计算.当有变量参与运算时,会先取出内存中的数据,放入通用寄存器中,再 ...

  2. ldr和adr在使用标号表达式作为操作数的区别

    ARM汇编有ldr指令以及ldr.adr伪指令,他门都可以将标号表达式作为操作数,下面通过分析一段代码以及对应的反汇编结果来说明它们的区别. ldr     r0, _start adr     r0 ...

  3. C++函数调用的反汇编过程及Thunk应用

    x86汇编基础知识 1. 汇编常用寄存器 esp,(Extended stack pointer)栈顶指针.因为x86的栈内存是向下扩展的,因此当push入栈时,esp–.pop出栈时,esp++.e ...

  4. 《天书夜读:从汇编语言到windows内核编程》三 练习反汇编C语言程序

    1) Debug版本算法反汇编,现有如下3×3矩阵相乘的程序: #define SIZE 3 int MyFunction(int a[SIZE][SIZE],int b[SIZE][SIZE],in ...

  5. C++反汇编第四讲,反汇编中识别继承关系,父类,子类,成员对象

    C++反汇编第四讲,反汇编中识别继承关系,父类,子类,成员对象 讲解目录: 1.各类在内存中的表现形式   备注: 主要复习开发知识,和反汇编没有关系,但是是理解反汇编的前提.     2.子类继承父 ...

  6. C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式.

    C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式. 目录: 1.多重继承在内存中的表现形式 多重继承在汇编中的表现形式 2.菱形继承 普通的菱形继承 虚继承 汇编中的表现形 ...

  7. C++11 constexpr常量表达式

    常量表达式函数 要求: 函数体内只有单一的return返回语句 例如: constexpr int data() { const int i=1; //含有除了return以外的语句 return i ...

  8. C++反汇编-结构体和类

    学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记 对象的内存布局 一般计算公式: 对象内存大小 = sizeof(数据成员1)+ sizeof(数据成员2) +. ...

  9. c++反汇编与逆向分析 小结

    第一章  熟悉工作环境和相关工具 1.1 熟悉OllyDBG  操作技巧 1.2 反汇编静态分析工具 IDA(最专业的逆向工具)     快捷键    功能     Enter     跟进函数实现 ...

随机推荐

  1. 【哈希表】leetcode454——四数相加II

    编号454:四数相加II 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为 ...

  2. 为什么国内的好多具备 HTTPS 的网站却没有使用 HTTPS 重定向功能

    为什么国内的好多具备 HTTPS 的网站却没有使用 HTTPS 重定向功能 HTTPS 重定向 good demos ️ HTTPS http://www.xgqfrms.xyz/ https://w ...

  3. SVG animation(text, background)

    SVG animation(text, background) demo https://www.happyelements.com/ LICEcap bug Giphy 低帧率 gif https: ...

  4. React & update state with props & Object.assign

    React & update state with props & Object.assign Object.assign({}, oldObj, newObj) https://re ...

  5. Flutter 区分开发环境和生产环境

    Uri _baseUrl; final isProd = const bool.fromEnvironment('dart.vm.product'); if (isProd) { _baseUrl = ...

  6. NGK新加坡峰会:超级节点和开源代码为DeFi生态带来新曙光!

    据伦敦金融时报以及纽约商业报等多家媒体报道的消息,1月31日,2021 NGK区块链峰会于新加坡正式开幕,全球多位区块链研究所专家线上受邀出席参会,NGK灵石技术研发Clifton先生,法国区块链专家 ...

  7. 在多线程编程中不要使用sleep()、usleep()函数

    这两个函数是非线程安全的,可能会造成程序卡死. 对于c++程序,建议使用std::this_thread::sleep_for()和std::this_thread::yield()代替. 纯c程序可 ...

  8. 简单梳理下 Vue3 的新特性

    在 Vue3 测试版刚刚发布的时候,我就学习了下 Composition API,但没想到正式版时隔一年多才出来,看了一下发现还是增加了不少新特性的,在这里我就将它们一一梳理一遍. 本文章只详细阐述 ...

  9. TERSUS无代码开发(笔记09)-简单实例前端样式设计

    前端常用样式设计 =========================================================================================== ...

  10. js中函数调用时,对参数个数和类型没有要求

    因为js是一种弱类型的编程语言,对数据类型的要求没有其他编程语言的要求严格,所以在定义函数的时候不需要像java一样对其传入参数的类型进行定,也对传入参数的个数没有要求. js函数的参数与大多数其他语 ...