源程序如下:
#include <stdio.h>
int main()
{
return 0;
}
通过vc++6.0的反汇编查看,代码如下
1: #include <stdio.h>
2: int main()
3: {
00401010 push ebp;将ebp寄存器的内容放入栈中,esp+4
00401011 mov ebp,esp;将esp内容放入ebp寄存器
00401013 sub esp,40h;将esp减去64,后面有解释
00401016 push ebx;将ebx内容放入栈中,esp+4
00401017 push esi;将esi内容放入栈中,esp+4
00401018 push edi;将edi内容放入栈中,esp+4
00401019 lea edi,[ebp-40h];现在ebp存放的是原栈顶地址,ebp-40h是将原栈顶地址减去64,以便于下面的随机赋值
0040101C mov ecx,10h;将16赋给ecx
00401021 mov eax,0CCCCCCCCh;将0CCCCCCCCh赋给eax
00401026 rep stos dword ptr [edi];用eax的值填充edi所指内存,然后edi+4,循环ecx次
4: return 0;
00401028 xor eax,eax;eax清零,返回值存放在eax中
5: }
0040102A pop edi;弹出值,放入edi寄存器中,esp-4
0040102B pop esi;弹出值,放入esi寄存器中,esp-4
0040102C pop ebx;弹出值,放入ebx寄存器中,esp-4
0040102D mov esp,ebp:恢复栈顶
0040102F pop ebp;弹出值,放入ebp寄存器中,esp-4
00401030 ret
下面针对上面的代码及注释进行分析:
1、 红色部分为原C语言程序,不做解释;
2、 其他为反汇编代码
①、 汇编代码中的edi,esi,ebx,esp,ebp为32位汇编指令,同16位汇编指令,di,si,bx,sp,bp。
②、 push ebp把EBP寄存器中的内容放到堆栈中,同时ESP寄存器中存放的地址减少四个字节;
③、 mov ebp,esp把栈顶指针赋给EBP寄存器;
④、 sub esp,40h将ESP寄存器内地址减去64,用以存放局部变量;
⑤、 push ebx和push esi和push edi 向堆栈中插入寄存器中数据;
⑥、 lea edi,[ebp-40h],首先,ebp-40h指的是栈顶指针减去64,即存放局部变量那段数据的低地址段,现在edi中存放ebp-40h;
⑦、 下面三行,将10h即16赋给ecx,然后将0CCCCCCCCh赋给eax(随机),(这就是有时候调试时,目标地址以为的地方为CC的原因了)rep stos dword ptr[edi]将重复填充存放局部变量的那段区间,重复次数为ecx内容10h,即16次,存放数据为eax内容,并且每次edi增加四个字节,刚好64个字节即40h;
⑧、 xor eax,eax所有的返回值均存放在eax中,此指令将eax清零;
⑨、 下面就是出栈了,直到mov esp,ebp将EBP寄存器中保存的栈顶指针赋给ESP;然后弹出EBP,ret返回。