C语言程序的汇编分析3——for循环

1、 程序如下:

#include <stdio.h>

int func(int a,int b)

{

      int c=a+b,i;

      for (i=0;i<50;i++)

      {

             c+=i;

      }

      return c;

}

int main()

{

      int result;

      result=func(1,2);

      printf("%d/n",result);

      return 0;

}

分析如下:

㈠、首先我们可以查看主函数的反汇编代码,如下:

11:  int main()

12:  {

00401090  push       ebp

00401091  mov        ebp,esp

00401093  sub        esp,44h

00401096  push       ebx

00401097  push       esi

00401098  push       edi

00401099  lea        edi,[ebp-44h]

0040109C  mov        ecx,11h

004010A1  mov        eax,0CCCCCCCCh

004010A6  rep stos   dword ptr [edi]

13:      int result;

14:      result=func(1,2);

004010A8  push       2

004010AA  push       1

004010AC  call       @ILT+5(_func) (0040100a)

004010B1  add        esp,8

004010B4  mov        dword ptr [ebp-4],eax[雨林木风1] 

15:      printf("%d/n",result);

004010B7  mov        eax,dword ptr [ebp-4]

004010BA  push       eax

004010BB  push       offset string "%d/n" (0042210c)

004010C0  call       printf (0040d6f0)

004010C5  add        esp,8

16:      return 0;

004010C8  xor        eax,eax

17:  }

004010CA  pop        edi

004010CB  pop        esi

004010CC  pop        ebx

004010CD  add        esp,44h

004010D0  cmp        ebp,esp

004010D2  call       __chkesp (004010e0)

004010D7  mov        esp,ebp

004010D9  pop        ebp

004010DA  ret

 

分析如下:

Ⅰ、

其中红色部分为C语言源程序,不再解释,而蓝色的,与上一节解释相同。

Ⅱ、

解释一下黄色代码:

004010B7  mov        eax,dword ptr [ebp-4[雨林木风2] ]   

004010BA  push       eax[雨林木风3] 

004010BB  push       offset string "%d/n" (0042210c[雨林木风4] )

004010C0  call       printf (0040d6f0[雨林木风5] 

004010C5  add        esp,8[雨林木风6]  

 

㈡、下面我们查看调用函数的反汇编代码,如下:

分析如下:

2:   int func(int a,int b)

3:   {

00401020  push       ebp

00401021  mov        ebp,esp

00401023  sub        esp,48h

00401026  push       ebx

00401027  push       esi

00401028  push       edi

00401029  lea        edi,[ebp-48h]

0040102C  mov        ecx,12h

00401031  mov        eax,0CCCCCCCCh

00401036  rep stos   dword ptr [edi]

4:       int c=a+b,i;

00401038  mov        eax,dword ptr [ebp+8]

0040103B  add        eax,dword ptr [ebp+0Ch]

0040103E  mov        dword ptr [ebp-4],eax

5:       for (i=0;i<50;i++)

00401041  mov        dword ptr [ebp-8],0

00401048  jmp        func+33h (00401053)

0040104A  mov        ecx,dword ptr [ebp-8]

0040104D  add        ecx,1

00401050  mov        dword ptr [ebp-8],ecx

00401053  cmp        dword ptr [ebp-8],32h

00401057  jge        func+44h (00401064)

6:       {

7:           c+=i;

00401059  mov        edx,dword ptr [ebp-4]

0040105C  add        edx,dword ptr [ebp-8]

0040105F  mov        dword ptr [ebp-4],edx

8:       }

00401062  jmp        func+2Ah (0040104a)

9:       return c;

00401064  mov        eax,dword ptr [ebp-4]

10:  }

00401067  pop        edi

00401068  pop        esi

00401069   pop        ebx

0040106A  mov        esp,ebp

0040106C  pop        ebp

0040106D  ret

Ⅰ、

其中红色部分为C语言源程序,不再解释,蓝色部分,仔细观察会发现变成了48h,即72,为什么呢,因为vc++6.0默认的是40h,即六十四字节,而现在定义了两个变量。所以就变成了48h

Ⅱ、

绿色部分:为for循环的反汇编代码

00401041  mov        dword ptr [ebp-8],0[雨林木风7] 

00401048  jmp        func+33h (00401053[雨林木风8] )

0040104A  mov        ecx,dword ptr [ebp-8[雨林木风9] ]

0040104D  add        ecx,1[雨林木风10] 

00401050  mov        dword ptr [ebp-8],ecx[雨林木风11] 

00401053  cmp        dword ptr [ebp-8],32h[雨林木风12] 

00401057  jge        func+44h (00401064[雨林木风13] )

6:       {

7:           c+=i;

00401059  mov        edx,dword ptr [ebp-4]

0040105C  add        edx,dword ptr [ebp-8]

0040105F  mov        dword ptr [ebp-4],edx

8:       }

00401062  jmp        func+2Ah (0040104a)

 

Ⅲ、

其他都与上一节一样了,不解释了。。。


 [雨林木风1]将返回值赋给ebp-4所指内存

 [雨林木风2]ebp-4所指内存为result

 [雨林木风3]将参数result入栈,esp-4

 [雨林木风4]参数入栈

 [雨林木风5]调用printf

 [雨林木风6]恢复堆栈

 [雨林木风7]Ebp-8中存放的是变量i,初始化为0

 [雨林木风8]跳转到地址00401053h

 [雨林木风9]ebp-8中存放的数据即i放到ecx

 [雨林木风11]i+1后的数据赋给i

 [雨林木风12]比较i50的大小

 [雨林木风13]根据上面,若大于等于则跳转


版权声明:本文为aizailushang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。