C----函数递归之反汇编

环境

win10
vc6.0
debug

代码

关于求阶层问题:n!=n(n-1)!;(n-1)! = (n-1)(n-2)!
例如5!=5(4)! 4!=43! 3!=32! 2!=21 函数递归的出口是1,所以函数递归最重要的条件是去寻找递归的出口

int fun(int i)
{
  int sum = 0;
  if (i == 1)
  {
    return 1;
  }
  else
  {
    sum = i*fun(i-1);
  }
  return sum ;
}
int main()
{	
  int  n = 0;
  printf("请输入你要求的阶层\r\n");
  scanf("%d",&n);
  int result1 = fun(n);
  printf("%d",result1);
  return 0;
}

关于调试去栈的问题

1.main栈

2.fun(0x00000005)栈 i=5;sum = 0

3.fun(0x00000004)栈 i=4;sum = 0

4.fun(0x00000003)栈 i=3;sum = 0

5.fun(0x00000002)栈 i=2;sum = 0

6.fun(0x00000001)栈 i=1;sum = 0

7.当 i = 1,sum=0时 走完if(i==1)时会走return 1 return之后直接走到fun的右括号,黄色箭头代表即将执行但还未执行的代码.

8.清理函数fun(0x00000001)栈空间并进入fun(0x00000002)的栈

9.执行完以后
sum=2;

10.清理函数fun(0x00000003)的栈
i=3 * fun(3-1) ==6 sum =6;

以此直到fun(0x00000005)的栈清理完为止

函数递归执行图

汇编代码分析

21:   int main()
22:   {
0040D790 55                   push        ebp
0040D791 8B EC                mov         ebp,esp
0040D793 83 EC 48             sub         esp,48h
0040D796 53                   push        ebx
0040D797 56                   push        esi
0040D798 57                   push        edi
0040D799 8D 7D B8             lea         edi,[ebp-48h]
0040D79C B9 12 00 00 00       mov         ecx,12h
0040D7A1 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
0040D7A6 F3 AB                rep stos    dword ptr [edi]
23:     int  n = 0;
0040D7A8 C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0 //[ebp-4]第一个局部变量 [ebp-8]就是代表第2个局部变量;[ebp-C]就是代表第3个局部变量以此类推
24:     printf("请输入你要求的阶层\r\n");
0040D7AF 68 A4 2F 42 00       push        offset string "\xc7\xeb\xca\xe4\xc8\xeb\xc4\xe3\xcf\xeb\xd2\xaa\xc7\xf3\xb5\xc4" (00422f
0040D7B4 E8 87 39 FF FF       call        printf (00401140)
0040D7B9 83 C4 04             add         esp,4
25:     scanf("%d",&n);
0040D7BC 8D 45 FC             lea         eax,[ebp-4]
0040D7BF 50                   push        eax
0040D7C0 68 1C 20 42 00       push        offset string "%d" (0042201c)
0040D7C5 E8 16 22 00 00       call        scanf (0040f9e0)
0040D7CA 83 C4 08             add         esp,8
26:     int result1 = fun(n);
0040D7CD 8B 4D FC             mov         ecx,dword ptr [ebp-4]
0040D7D0 51                   push        ecx
0040D7D1 E8 43 38 FF FF       call        @ILT+20(fun) (00401019)
0040D7D6 83 C4 04             add         esp,4
0040D7D9 89 45 F8             mov         dword ptr [ebp-8],eax
27:     printf("%d",result1);
0040D7DC 8B 55 F8             mov         edx,dword ptr [ebp-8]
0040D7DF 52                   push        edx
0040D7E0 68 1C 20 42 00       push        offset string "%d" (0042201c)
0040D7E5 E8 56 39 FF FF       call        printf (00401140)
0040D7EA 83 C4 08             add         esp,8
28:     return 0;
0040D7ED 33 C0                xor         eax,eax
29:   }
posted @ 2024-09-18 20:32  不会笑的孩子  阅读(10)  评论(0编辑  收藏  举报