[原创]for循环反汇编总结
说来惭愧,本人对逆向分析一事倍感吃力,料定是基础不牢所致。故下决心恶补基础知识,现定将《C++ Primer》从头到尾再复习一遍,无分难易,并将其逆向分析一翻。一来复习C++,二来复习汇编,三来积攒逆向知识。望与大家相互学习,争取早日可与大牛比肩。此,感谢论坛热心朋友 疯子和hilter的热心帮助,他们一翻指点让我大有茅塞顿开之感。
—————————————————————————————————————————————
for(i=1;i<=100;++i)
00881008 mov eax,1
0088100D xor ecx,ecx
0088100F nop
{
sum+=i;
00881010 add edi,eax
00881012 lea ecx,[ecx+eax+1]
00881016 lea edx,[edx+eax+2]
0088101A lea esi,[esi+eax+3]
0088101E add eax,4
00881021 cmp eax,64h
00881024 jle main+10h (881010h)
}
cout<<sum;
00881026 add esi,edx
00881028 add esi,ecx
0088102A mov ecx,dword ptr [__imp_std::cout (882048h)]
00881030 add edi,esi
00881032 push edi
以上是VS2010自带的反汇编代码
在发行版本的FOR循环中,很明显和调试版中FOR循环特征变化很大。此版本中对要求和的所有数字进行了分组,在循环的外边再进行最终的求和。当时我最困惑的就是LEA这个指令,当时我记得这个指令应该是取地址的,想不明白他取个地址干什么。最后经过实验以及网上查阅资料,发现此时的LEA指令在功能上和MOV是一样的。
比如: lea ecx,[ecx+eax+1] 功能上和 mov ecx,ecx+eax+1 一样,但很明显mov不能这么用。(
我个人这么理解,但是否真这样或者是否严密还请大家指正)同时此处也完成了各个组内的累加(这也是我困惑的一个地方,因为当时不明白LEA的作用,一直以为是取地址)。
上面说到分组,可是这个组是怎么分的呢?究竟分多少组呢?
这个经过试验发现 分成几组和循环次数有关 一般是2,3,4组(循环次数此时是2或者3 的倍数。为什么不再多点分6,8组呢?或许因为寄存器个数不够?或者分组太多达不到最好的优化效果了吧。。。。)。
既然如此,那么循环次数不是2或者3的倍数怎么办呢?
for(i=1;i<=97;++i)
00C41007 mov eax,1
00C4100C lea esp,[esp]
{
sum+=i;
00C41010 add edx,eax
00C41012 lea ecx,[ecx+eax+1]
00C41016 add eax,2
00C41019 cmp eax,60h
00C4101C jle main+10h (0C41010h)
int i;
for(i=1;i<=97;++i)
00C4101E cmp eax,61h
00C41021 jg main+25h (0C41025h)
{
sum+=i;
00C41023 mov esi,eax
00C41025 add ecx,edx
00C41027 add ecx,esi
}
看出来了吧,它直接修改了咱们的控制条件,进行了2次循环(如果第二次算是个循环的话,其实它更像一个IF语句)
不过最后为什么非通过ESI来进行累加我还是不太清楚,不可以直接ADD ECX,EAX吗?还望大家指教!
