环境:VC++
C程序:
#include "stdio.h"int main()
{int i=1,sum=0;while(i<=100){sum+=i;i++;}printf("%d\n",sum);return 0;
}
用while计算1到100的值,功能很简单,让我们看看反汇编
首先在main函数的入口,看到一条汇编不懂意思
0040101C B9 12 00 00 00 mov ecx,12h
00401021 B8 CC CC CC CC mov eax,0CCCCCCCCh
00401026 F3 AB rep stos dword ptr [edi]
查了资料,知道了
- rep指令:重复
stos dword ptr [edi]
指令.ECX的值是重复的次数,每次ECX都会减一,到0就不执行了 - stos:将eax中的值拷贝到ES:EDI指向的地址,也就是上面的
dword ptr [edi]
- es:附加段寄存器,存放当前执行程序中一个辅助数据段的段地址
我们利用VC++反汇编可以查看一下,当执行了一次rep stos dword ptr [edi]
命令后
while的反汇编程序:
5: int i=1,sum=0;
00401028 C7 45 FC 01 00 00 00 mov dword ptr [ebp-4],1 //栈中[ebp-4]的值为1
0040102F C7 45 F8 00 00 00 00 mov dword ptr [ebp-8],0//栈中[ebp-8]的值为0
6: while(i<=100){
00401036 83 7D FC 64 cmp dword ptr [ebp-4],64h //比较i和100的值
0040103A 7F 14 jg main+40h (00401050) //大于跳转到00401050执行
7: sum+=i;
0040103C 8B 45 F8 mov eax,dword ptr [ebp-8]
0040103F 03 45 FC add eax,dword ptr [ebp-4] //相加
00401042 89 45 F8 mov dword ptr [ebp-8],eax //[ebp-8]相当于sum
8: i++;
00401045 8B 4D FC mov ecx,dword ptr [ebp-4]
00401048 83 C1 01 add ecx,1
0040104B 89 4D FC mov dword ptr [ebp-4],ecx
9: }
0040104E EB E6 jmp main+26h (00401036) //执行100次之后跳转到00401036执行
10: printf("%d\n",sum);
00401050 8B 55 F8 mov edx,dword ptr [ebp-8]
00401053 52 push edx
00401054 68 1C 20 42 00 push offset string "%d" (0042201c)
00401059 E8 32 00 00 00 call printf (00401090)
0040105E 83 C4 08 add esp,8
执行一个函数,程序会先把ebp的值压入栈,把esp赋值给ebp
- jg:大于跳转指令
反汇编实现:
#include "stdio.h"int main()
{/*int i=1,sum=0;while(i<=100){sum+=i;i++;}printf("%d\n",sum);*/char *str="sum=%d\n";__asm{mov eax,1mov ebx,0mov ecx,1sum : cmp ecx,100jg endadd ebx,eaxinc eaxinc ecxjmp sumend : push ebxpush strcall printfadd esp,8}return 0;}