逆向VC对乘法的优化
2013-06-02 20:08
211 查看
还是看的那篇算法大全的文章,见有个九九乘法表,想来应该是白痴的嵌套循环加IMUL等指令的东西,敲下代码。OD一反,却见不到我所料了IMUL,而只有那鹤立鸡群的 add ebx,edi。。。。。。。
程序源代码:
跳过废话看代码:
00401000 /$ 53 push ebx
00401001 |. 56 push esi
00401002 |. 57 push edi ; 寄存器保存
00401003 |. 68 3C704000 push 0040703C
00401008 |. E8 53000000 call 00401060 ; 输出换行符
0040100D |. 83C4 04 add esp, 4 ; 恢复堆栈
00401010 |. BF 01000000 mov edi, 1 ; for:i=1
00401015 |> BE 01000000 /mov esi, 1 ; for:j=1
0040101A |. 8BDF |mov ebx, edi
0040101C |> 53 |push ebx ; result
0040101D |. 56 |push esi ; j
0040101E |. 57 |push edi ; i
0040101F |. 68 30704000 |push 00407030 ; ASCII "%d*%d=%-3d"
00401024 |. E8 37000000 |call 00401060 ; 第一次必然输出1*1=1
00401029 |. 83C4 10 |add esp, 10 ; 恢复堆栈
0040102C |. 46 |inc esi ; j++
0040102D |. 03DF |add ebx, edi ; result=result+i(为什么会这样啊!!请看最下面分解)
0040102F |. 83FE 0A |cmp esi, 0A ; cmp j,10
00401032 |.^ 7E E8 |jle short 0040101C ; 不过10次循环则继续循环
00401034 |. 68 3C704000 |push 0040703C
00401039 |. E8 22000000 |call 00401060 ; 输出换行符
0040103E |. 83C4 04 |add esp, 4
00401041 |. 47 |inc edi ; i++
00401042 |. 83FF 0A |cmp edi, 0A
00401045 |.^ 7E CE \jle short 00401015 ; 10次i循环。。
00401047 |. 68 3C704000 push 0040703C
0040104C |. E8 0F000000 call 00401060 ; 换行符
00401051 |. 83C4 04 add esp, 4
00401054 |. 5F pop edi
00401055 |. 5E pop esi
00401056 |. 5B pop ebx
00401057 \. C3 retn
上面的代码输出了九九乘法表,但是我们甚至没看到一个mul或imul!那是因为VC的优化效果!
以下是九九乘法表的第二行。
2*1=2
2*2=4
2*3=6
2*4=8
2*5=10
………
这里的1,2,3,4,5是等差数列2,4,6,8,10是等比数列,而被乘数恒为2
我们发现形如此式子的计算结果往往是上一条式子的运算结果加上被乘数。
这里的代码正是将ebx作为累加器把之前的结果保存起来,再不失时机地加上外循环的计数变量
而我们原以为能大显身手的j变量因为上面的数学规律的发现而只能充当循环结束的判断变量了!!
程序源代码:
#include <math.h> #include <stdio.h> #include <stdlib.h> void main() { int i,j,result; printf("\n"); for(i=1;i<=10;i++) { for(j=1;j<=10;j++) { result=i*j; printf("%d*%d=%-3d",i,j,result); } printf("\n");/*每一行后换行*/ } printf("\n"); }
跳过废话看代码:
00401000 /$ 53 push ebx
00401001 |. 56 push esi
00401002 |. 57 push edi ; 寄存器保存
00401003 |. 68 3C704000 push 0040703C
00401008 |. E8 53000000 call 00401060 ; 输出换行符
0040100D |. 83C4 04 add esp, 4 ; 恢复堆栈
00401010 |. BF 01000000 mov edi, 1 ; for:i=1
00401015 |> BE 01000000 /mov esi, 1 ; for:j=1
0040101A |. 8BDF |mov ebx, edi
0040101C |> 53 |push ebx ; result
0040101D |. 56 |push esi ; j
0040101E |. 57 |push edi ; i
0040101F |. 68 30704000 |push 00407030 ; ASCII "%d*%d=%-3d"
00401024 |. E8 37000000 |call 00401060 ; 第一次必然输出1*1=1
00401029 |. 83C4 10 |add esp, 10 ; 恢复堆栈
0040102C |. 46 |inc esi ; j++
0040102D |. 03DF |add ebx, edi ; result=result+i(为什么会这样啊!!请看最下面分解)
0040102F |. 83FE 0A |cmp esi, 0A ; cmp j,10
00401032 |.^ 7E E8 |jle short 0040101C ; 不过10次循环则继续循环
00401034 |. 68 3C704000 |push 0040703C
00401039 |. E8 22000000 |call 00401060 ; 输出换行符
0040103E |. 83C4 04 |add esp, 4
00401041 |. 47 |inc edi ; i++
00401042 |. 83FF 0A |cmp edi, 0A
00401045 |.^ 7E CE \jle short 00401015 ; 10次i循环。。
00401047 |. 68 3C704000 push 0040703C
0040104C |. E8 0F000000 call 00401060 ; 换行符
00401051 |. 83C4 04 add esp, 4
00401054 |. 5F pop edi
00401055 |. 5E pop esi
00401056 |. 5B pop ebx
00401057 \. C3 retn
上面的代码输出了九九乘法表,但是我们甚至没看到一个mul或imul!那是因为VC的优化效果!
以下是九九乘法表的第二行。
2*1=2
2*2=4
2*3=6
2*4=8
2*5=10
………
这里的1,2,3,4,5是等差数列2,4,6,8,10是等比数列,而被乘数恒为2
我们发现形如此式子的计算结果往往是上一条式子的运算结果加上被乘数。
这里的代码正是将ebx作为累加器把之前的结果保存起来,再不失时机地加上外循环的计数变量
而我们原以为能大显身手的j变量因为上面的数学规律的发现而只能充当循环结束的判断变量了!!
相关文章推荐
- 《黑客免杀攻防》读书笔记-软件逆向工程(8)乘法与除法的识别与优化原理
- 代码逆向(七)——乘法的识别与优化原理
- 逆向工程之表达式优化识别(2)-乘法
- VC 编译器将除法优化为乘法的策略
- BZOJ 1875 [SDOI 2009] HH去散步 (DP,矩阵乘法优化)
- 矩阵乘法优化递归式
- 实践记录: G++4.x与VC 2005 局部优化比较: >位操作优化一例及volatile优化
- ARM处理器NEON编程及优化技巧——矩阵乘法的实例
- POJ 3213 矩阵乘法(优化)
- CUDA: 矩阵乘法优化
- SICP 习题 (2.11)解题总结:区间乘法的优化
- BZOJ 2875: [Noi2012]随机数生成器【矩阵乘法优化递推
- vc界面优化类之CButtonST类
- vs2010 vc6 编译体积优化
- 逆向课程第五讲逆向中的优化方式,除法原理,以及除法优化下
- 《黑客免杀攻防》读书笔记-软件逆向工程(7)加法与减法的识别与优化原理
- 用VC编译ffmpeg(包括汇编优化) 的心得和体会
- BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)
- cuda(2) 矩阵乘法优化过程
- 某公司面试题——怎样优化乘法?